如果不通过 createElementNS 处理,为什么动态 SVG 不能工作

2022-01-14 00:00:00 namespaces svg javascript

我试图在纯 JS 中操作 SVG,发现如果我不使用 createElementNSsetAttributeNS 等方法,它的行为将无法达到预期.

I was trying to manipulate SVG in plain JS and found that it won't behave as intended if I don't use methods like createElementNS and setAttributeNS.

<svg id="mydsvg" width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>

上述标记完美运行.但是如果您尝试通过以下代码添加另一个圈子,您将看不到它.

The above markup works perfectly. But if you try to add another circle via the following code, you won't see it.

var circle = createElement('circle');
circle.setAttribute('cx', 50);
....
document.getElementById('mysvg').appendChild(circle);

但是如果你使用 createElementNSsetAttributeNS,它会按预期工作.

But if you use createElementNS and setAttributeNS, it will work as expected.

最糟糕的是,createElementcreateElementNS 都会创建相同的 DOM 文本.

To be worst, both createElement and createElementNS create identical DOM text.

推荐答案

它不起作用,因为规范说 SVG 元素必须存在于 SVG 命名空间中,而 createElement 在 html 命名空间中创建元素.解析器如何知道您是否想要创建一个与 src 属性一起使用的 html <a> 元素或 SVG <a> 元素xlink:href 属性是必需的.

It doesn't work because the specifications say that SVG elements must exist in the SVG namespace and createElement creates elements in the html namepace. How would a parser know otherwise whether you wanted to create an html <a> element which works with a src attribute or a SVG <a> element for which an `xlink:href attribute is required.

在命名空间未序列化的 html 中,事情看起来是一样的.在命名空间被序列化的 XML 中,它们不会.

In html where namespaces are not serialized things look the same. In XML where namespaces are serialized they don't.

html 中的 SVG 看起来像这样......

SVG in html looks like this...

<svg id="mydsvg" width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>

SVG 作为一个独立的文档看起来像这样

SVG as a standalone document would look like this

<svg xmlns="https://www.w3.org/2000/svg" id="mydsvg" width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>

圆圈继承其父级的命名空间.

The circle inherits the namespace of its parent.

相关文章