考虑这个带有 <text>
的简单 SVG包含一些 <tspan>
的元素年代:
<svg>
<text x="10" y="30">
Foo Bar Baz
<tspan x="30" dy="30">FooBar</tspan>
<tspan x="30" dy="30">FooBaz</tspan>
</text>
</svg>
现在假设我们要更改文本本身的值(在本例中为“Foo Bar Baz”),同时保持其
<tspan>
子孙。如果我们使用 textContent
, innerHTML
(现代浏览器支持 innerHTML
用于 SVG)等将替换所有内容,包括 child :document.querySelector("text").textContent = "New Foo";
<svg>
<text x="10" y="30">
Foo Bar Baz
<tspan x="30" dy="30">FooBar</tspan>
<tspan x="30" dy="30">FooBaz</tspan>
</text>
</svg>
一种解决方法是获取子节点的第一个 NodeList 元素,通常是文本本身:
document.querySelector("text").childNodes[0].textContent = "New Foo";
<svg>
<text x="10" y="30">
Foo Bar Baz
<tspan x="30" dy="30">FooBar</tspan>
<tspan x="30" dy="30">FooBaz</tspan>
</text>
</svg>
但是,这种解决方法非常hacky。 “为什么?”,你可能会问……好吧,在集合中使用硬编码索引对我来说已经够难了。另外,就像我上面写的,集合中的第一个元素通常是文本本身,但我不知道这是否依赖于实现,因此,新的浏览器可以简单地改变集合中的顺序,实现不同的序列.
因此,我的问题标题中的正确方法是:是否有一个属性或任何其他方法可以仅在 SVG
<text>
中专门更改文本内容元素?
最佳答案
在我看来,您有两种选择。 1)在您查找文本节点的最后一个示例的基础上构建。您知道有一个带有内容的文本节点。可以测试 <text>
的所有子节点查看它是否是文本节点,然后替换该节点。 2) 你把文本节点变成 <tspan>
元素就像其他子元素一样。这在视觉上没有任何区别,同时如果需要,更容易引用元素并对其进行样式设置。添加这个元素的“成本”是最小的。
document.querySelector("text > .first").textContent = "New Foo";
<svg>
<text x="10" y="30">
<tspan class="first">Foo Bar Baz</tspan>
<tspan x="30" dy="30">FooBar</tspan>
<tspan x="30" dy="30">FooBaz</tspan>
</text>
</svg>
关于javascript - 更改 SVG <text> 而不更改其子 <tspan> 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68661530/