【问题标题】:Appending path child within SVG Using Javascript使用 Javascript 在 SVG 中附加路径子项
【发布时间】:2012-05-11 05:56:54
【问题描述】:

美好的一天,

我在创建路径并在 SVG 元素中使用“appendChild”显示它时遇到了难以置信的困难。

我必须遗漏一些非常简单的东西,因为我已经倾注了 W3C 的规范、w3schools.com、这里的各种帖子并尝试以各种方式忍者谷歌。

我在 FireFox 和 Chrome 中进行测试。

我有一个简单的 svg 文件:

<svg xmlns:svg ... id="fullPageID">
 <image id="timer1" x="100" y="100" width="100px" height="100px" xlink:href="../component/timer/timer1.svg" />  
 <image id="battery1" x="200" y="200" width="100px" height="100px" xlink:href="../component/battery/30x20_ochre.svg" />
 <script xlink:href="pathMaker.js" type="text/javascript" id="pathMaker" />  
</svg>

我尝试使用的脚本如下所示:

newpath = document.createElementNS("SVG","path");  
newpath.setAttribute("id", "pathIdD");  
newpath.setAttribute("d", "M 1,97.857143 C 19.285714,96.428571 24.016862,131.64801 90.714286,132.85714 140.78762,133.7649 202.79376,66.16041 202.79376,66.16041");  
newpath.setAttribute("stroke", "black");  
newpath.setAttribute("stroke-width", 3);  
newpath.setAttribute("opacity", 1);  
newpath.setAttribute("fill", "none");

document.getElementById("fullPageID").appendChild(newpath);

我只想做一些简单的工作。我是否认为我不需要像 Library to generate SVG Path with Javascript? 那样复杂的解决方案?

非常感谢。

【问题讨论】:

  • 您可能想“接受”其中一个答案。

标签: javascript svg


【解决方案1】:

有两个问题:

  1. 正如已经指出的,你必须使用完整的命名空间 uri,所以在这种情况下:

    newpath = document.createElementNS('http://www.w3.org/2000/svg',"path");  
    
  2. 属性的设置也需要考虑命名空间。好消息是你可以传入null 作为命名空间uri,所以:

    newpath.setAttributeNS(null, "d", "M 1,97.857143 C 19.285714,96.428571 24.016862,131.64801 90.714286,132.85714 140.78762,133.7649 202.79376,66.16041 202.79376,66.16041");
    

另外,这里有两种方法可以更轻松地处理 svg 命名空间(假设它是一个独立的 svg,而不是嵌入在 HTML 中):

  • 要引用 svg 元素,您可以使用 document.rootElement,而不是给它一个 ID。
  • document.rootElement.getAttribute(null, "xmlns") 返回一个空字符串(虽然请求其他属性确实可以使用此方法。相反,请使用 document.rootElement.namespaceURI

因此,在您的代码中,您可以进行以下重写:

发件人:

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

收件人:

 newpath = document.createElementNS(document.rootElement.namespaceURI,"path");  

要附加元素,您可以从:

document.getElementById("fullPageID").appendChild(newpath);

到:

document.rootElement.appendChild(newpath);

所以最终的脚本是:

newpath = document.createElementNS(document.rootElement.namespaceURI,"path");  
newpath.setAttributeNS(null, "id", "pathIdD");  
newpath.setAttributeNS(null, "d", "M 1,97.857143 C 19.285714,96.428571 24.016862,131.64801 90.714286,132.85714 140.78762,133.7649 202.79376,66.16041 202.79376,66.16041");  
newpath.setAttributeNS(null, "stroke", "black"); 
newpath.setAttributeNS(null, "stroke-width", 3);  
newpath.setAttributeNS(null, "opacity", 1);  
newpath.setAttributeNS(null, "fill", "none");

document.rootElement.appendChild(newpath);

【讨论】:

  • #2 不正确;使用setAttribute(a,b) 等效于setAttributeNS(null,a,b):它也同样有效。
  • 确认上面的评论——我一直成功使用setAttribute(a,b)。至少可以在 Safari、Firefox 和 Chrome 上成功运行。
  • #2 并没有错,因为它是使用较新的 DOM 规范添加非 html 属性的“官方”方式。我遇到了 Chrome 的问题,其中属性存在于源代码检查器中,但未编译到样式中。即使它有效,也是因为 WebKit 和 Gecko 允许它兼容,而不是因为它真正等效。要点是:如果您不希望您的脚本在某个时候中断,最好使用预期的方法,而不是已经适应遗留证明的方法。我敢肯定,createElement 也曾在这些引擎中工作过。
  • 感谢您的快速回答和确认。我现在应该了解更多,因为我对 rootElement 有了基本的了解。每天只花几分钟时间学习新事物时,人们会忘记一些小事。
【解决方案2】:

命名空间必须是“http://www.w3.org/2000/svg”,而不是 createElementNS 调用中的“SVG”。

【讨论】:

    【解决方案3】:

    你可以得到一个免费的命名空间,并通过在其中放入一个路径元素,使用一个 id 隐藏它,然后克隆它来偷偷摸摸。这是一个使用 jQuery 的示例:

    HTML

    <svg ...>
      <path id="pathFactory"></path>
    </svg>
    

    CSS

    #pathFactory {
      display: none;
    }
    

    Javascript

    var path = $('#pathFactory').clone().removeAttr('id');
    

    您的路径变量现在是一个完整的工作路径,具有适当的命名空间,未隐藏并准备附加到 svg。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-16
      相关资源
      最近更新 更多