【问题标题】:Failed to execute 'appendChild' on 'Node': Only one element on document allowed无法在“节点”上执行“appendChild”:文档上只允许一个元素
【发布时间】:2017-05-09 06:55:41
【问题描述】:

我正在尝试加载一个外部 svg 文件,然后在其上写入额外的 SVG 元素。当我这样做时,我收到以下错误

在“节点”上执行“appendChild”失败:文档上只允许一个元素

当我在 Chrome 中检查时。

这是 HTML:

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="css/index.css">
    <title>Hello World</title>
  </head>
  <body>
      <svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="mySvg">
        <circle cx="40" cy="30" r="15" fill="#FF00FF"
          stroke="#000000" stroke-width="2" />
      </svg>
      <object data="img/drawing.svg" type="image/svg+xml"
        align="center" id="svgDrw" height="80vh"></object>
    <script type="text/javascript" src="js/problem.js"></script>
  </body>
</html>

这里是问题.js:

var svgXtraDoc;
var d = document.getElementById("svgDrw");

d.addEventListener("load",function(){

  // get the inner DOM 
  svgXtraDoc = d.contentDocument;
  // get the inner element by id
  svgRect1 = svgXtraDoc.getElementById("MyRect1");
  svgRect2 = svgXtraDoc.getElementById("MyRect2");
}, false);


function addRect() {
  var svgRect = document.createElementNS("http://www.w3.org/2000/svg", 
    "rect");
  svgRect.setAttribute("x", 100);
  svgRect.setAttribute("y", 100);
  svgRect.setAttribute("width", 100);
  svgRect.setAttribute("height", 100);
  svgRect.style.fill = "red";
  // mySvg.appendChild(svgRect);
  svgXtraDoc.appendChild(svgRect);
}

document.getElementById("mySvg").addEventListener("click", addRect);

...这里是drawing.svg,去掉了一些Inkscapy cruft:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   width="29.02857mm"
   height="37.092064mm"
   viewBox="0 0 102.85714 131.42857"
   id="svg2"
   version="1.1">
  <g
     id="layer1"
     transform="translate(-205.71428,-218.07649)">
    <rect
       style="stroke:none;fill-opacity:1;fill:#5eb056"
       id="MyRect1"
       width="102.85714"
       height="131.42857"
       x="205.71428"
       y="218.07649" />
    <rect
       style="fill:#000000;stroke:none;fill-opacity:1"
       id="MyRect2"
       width="42.857143"
       height="65.714287"
       x="231.42857"
       y="252.3622" />
  </g>
</svg>

点击圆时出现错误:导入的两矩形图中应该出现的矩形没有出现,并且报错“Failed to execute 'appendChild' on 'Node': Only one element on允许的文件。”显示在控制台中。

如果我更改此设置,以便将矩形添加到包含圆的 svg 中,即取消注释“// mySvg.appendChild(svgRect);”行,则矩形成功出现。

我也知道绘图文件已成功加载,因为在其他代码中(为简洁起见,此处未包含)我可以更改该文件中矩形的颜色。所以看来我可以访问文件中的现有元素,但不能添加元素。

我没有考虑外部加载的 SVG 与内联 SVG 的区别吗?

最后一件事——这是进入一个 Cordova 应用程序,所以我想保持它的小,所以首选纯 JavaScript 解决方案。如果必须,我会使用 JQuery 或 SnapSVG,但我的需求似乎足够简单,应该可以在没有外部库的情况下做到这一点。

【问题讨论】:

  • 我刚刚找到了解决问题的方法——我想添加指示事件位置的圆圈,所以我可以将它们放入原始文件中,并将描边和填充设置为无,然后使它们可见在适当的时间,而不是在事件发生时实际创建和添加它们。不过,我仍然对所问问题的答案感兴趣。

标签: javascript svg


【解决方案1】:

在我的例子中,DOM 正在抱怨,因为我试图在 文档本身中添加一个孩子:

document.appendChild(myElement);

我通过获取body标签的引用解决了这个问题:

document.body.appendChild(logger);

【讨论】:

  • 没错,因为文档只能有一个 元素,没有别的。所有其他元素都是 元素 的子元素
【解决方案2】:

文档的根节点和文档元素是有区别的。您想要的是 &lt;svg&gt; 文档元素,但 .contentDocument 为您提供根节点。

根节点是更上一层的层次结构。这意味着,&lt;svg&gt; 文档元素驻留在根节点内,而根节点可能只有一个 &lt;svg&gt; 子元素。

要获取文档元素,请执行以下操作:

svgXtraDoc = d.contentDocument.documentElement;

【讨论】:

    猜你喜欢
    • 2018-11-05
    • 2016-06-11
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 2015-01-20
    • 2016-04-12
    相关资源
    最近更新 更多