【问题标题】:Dynamically created SVG elements are not rendered by the browser浏览器不呈现动态创建的 SVG 元素
【发布时间】:2016-12-15 09:51:24
【问题描述】:

我正在尝试在我的 HTML 中使用 SVG 标记来呈现一些图形。这个问题非常棘手,因为我刚刚意识到问题出在以编程方式生成 SVG 时。

标记

我想要在我的页面中结束的是这段代码:

<svg>
  <circle cx="20" cy="20" r="15"></circle>
</svg>

如果你把它粘贴到一个页面中,一切都很好,一个黑色的圆圈就会呈现出来!

动态创建 SVG

但我想使用 Javascript 创建这个内容,所以我有这个:

var container = document.createElement("div");
var svg = document.createElement("svg");

var circle = document.createElement("circle");
circle.setAttribute("cx", "20");
circle.setAttribute("cy", "20");
circle.setAttribute("r", "15");

svg.appendChild(circle);
container.appendChild(svg);
document.body.appendChild(container);

好吧,尝试在小提琴或浏览器中执行此操作,您会看到它不会被渲染。当您检查 HTML 时,您会看到 circle 没有占用任何空间。

有什么问题?

【问题讨论】:

标签: javascript html svg


【解决方案1】:

你必须使用 "document.createElementNS("http://www.w3.org/2000/svg", "svg");" 来创建 svg 元素

var container = document.createElement("div");
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");

var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circle.setAttribute("cx", "20");
circle.setAttribute("cy", "20");
circle.setAttribute("r", "15");

svg.appendChild(circle);
container.appendChild(svg);
document.body.appendChild(container);

【讨论】:

  • 我在svg 中尝试过,但我认为circle 中不需要它...我明白了,谢谢。但是为什么circle 需要它呢? svg 中的 xmlns 是全局包含的 ns,因此它应该适用于所有嵌套元素...
  • 你必须通过调用document.createElementNS而不是document.createElement来从svg命名空间("http://www.w3.org/2000/svg")创建svg dom元素
  • 是的,我明白这一点。所以,我尝试的是仅在 svg 元素上调用 createElementNS。根据您的回答,它似乎不起作用,我还需要在 circle 元素上使用 createElementNS。好吧,我的问题是:为什么只在svg 上还不够?当您在 svg 元素上使用 xmlns 时,该元素内的所有内容都会看到架构,因此也无需在 circle 上指定 xmlns...
  • @Andry 元素的命名空间在创建时设置,之后不可更改。
【解决方案2】:

虽然您必须使用 document.createElementNS("http://www.w3.org/2000/svg", "svg"); 来创建父 svg 元素, 您并不严格要求对子元素使用该方法以在您的页面上获得正常运行的图形。如果您使用更复杂的图像,包括多个路径、defs、样式、标题等,例如从绘图程序导出的图像,为每个孩子调用 createElementNS() 可能会变得特别麻烦。

一种对我很有效的更快方法是创建父 svg 元素,然后一次性将其所有内容添加为 innerHTML。您的具体示例可以这样解决:

var container = document.createElement("div");
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var svgContent = '<circle cx="20" cy="20" r="15"></circle>';

svg.innerHTML = svgContent;
container.appendChild(svg);
document.body.appendChild(container);

【讨论】:

    【解决方案3】:

    <svg>
      <circle cx="20" cy="20" r="15"></circle>
    </svg>

    【讨论】:

    • 这是什么?提问者希望它是动态生成的,这是错误的
    • 这似乎只是复制问题的一部分,并没有回答任何问题。它还缺少作为正确解决方案的强制性 XML 命名空间声明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多