3

使用document.createElement创建svg元素时,会发现一个诡异的现象,svg元素无法在页面上显示,但是通过调试器,可以看到该svg元素的存在。

例如:运行以下代码

<body>
<svg
  xmlns="http://www.w3.org/2000/svg"
  version="1.1"
  width="100%"
  height="100%"
  id="svg"
>
  <defs>
    <marker
      id="markerArrow"
      markerWidth="10"
      markerHeight="10"
      refX="2"
      refY="6"
      orient="auto"
    >
      <path d="M2,2 L2,10 L10,6 L2,2" fill="rgba(207, 219, 230, 1)" />
    </marker>
  </defs>
</svg>
<script>
  const path = document.createElement("path");
  path.setAttribute("d", "M105,72 C105,100 105,100 173,100");
  path.setAttribute("fill", "none");
  path.setAttribute("stroke-width", "2px");
  path.setAttribute("stroke", "rgba(207, 219, 230, 1)");
  path.setAttribute("marker-end", "url(#markerArrow)");
  document.getElementById("svg").appendChild(path);
</script>
</body>

页面上无法显示path元素,但是可在调试器中看到该元素的存在。
image.png

解决方法是用document.createElementNS代替document.createElement,因为XML是有命名空间的。

const path = document.createElementNS(
  "http://www.w3.org/2000/svg",
  "path"
);

document.createElementNS

document.createElementNS与document.createElement类似,也用于创建标签节点,只是它需要一个额外的命名空间URI作为参数。此命名空间用于标识该节点属于哪种XML类型。

有效的命名空间URI

  • HTML: http://www.w3.org/1999/xhtml
  • SVG:http://www.w3.org/2000/svg
  • XBL:http://www.mozilla.org/xbl
  • XUL:http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul

命名空间为什么是必须的

一个xml文档可能包含多个软件模块的元素和属性,在不同软件模块中使用相同名称的元素或属性,可能会导致识别和冲突问题,而xml命名空间可以解决该问题。

结论

所以在svg中插入元素时,要使用document.createElementNS和setAttributeNS。即使使用setAttribute是生效的。

参考:
Document.createElementNS: What's the difference and why we need it


lijinxieyang
356 声望13 粉丝