2010-05-21 88 views
3

我正在动态地将<svg>元素附加到XHTML页面(Firefox 3.6.3)上的现有SVG岛。它正在崩溃浏览器。Firefox - 在SVG中动态嵌入<svg>元素

手工完成,这按预期工作:

<svg xmlns="http://www.w3.org/2000/svg"> 
    <svg xmlns="http://www.w3.org/2000/svg"> 
     ...   
    </svg> 
</svg> 

但是,如果动态地添加使用JavaScript这个元素,浏览器崩溃。简单的例子:

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title>SVG island example</title> 
    <script type="text/javascript"><![CDATA[ 
     function crash() 
     { 
      svgs = document.getElementsByTagNameNS("http://www.w3.org/2000/svg", "svg"); 

      for (var i = 0; i < svgs.length; i++) 
      { 
       var e = document.createElementNS("http://www.w3.org/2000/svg", "svg"); 
       svgs[i].appendChild(e); 
      } 
     } 
    ]]></script> 
</head> 
<body> 
    <svg id="mySVG" xmlns="http://www.w3.org/2000/svg"> 
    </svg> 
    <button onclick="crash()">Crash Firefox</button> 
</body> 
</html> 

有趣的是,如果我做一个getElementById,它的工作原理罚款。有趣的,但在我的情况并不特别有用,因为我存储指向SVGDocument s的指针。例如:

function doesntCrash() 
{ 
    var svg = document.getElementById("mySVG"); 
    var e = document.createElementNS("http://www.w3.org/2000/svg", "svg"); 
    svg.appendChild(e); 
} 

据我所知,这是一个Firefox的bug。 有没有人对此事有任何洞见?

被更新(解决方案):(!啧,啧 如下所述,问题是由getElementsByTagNameNS电话,我误以为本地阵列返回HTMLCollection快速hackaround的“活跃度”会要么将数组长度存储在变量中,如果只是追加的话。更好的解决方案可能是将阵列内容复制到本机阵列,如here所述。下面是一个使用该方法更新时间:

function doesntCrash() 
{ 
    var svgs = document.getElementsByTagNameNS("http://www.w3.org/2000/svg", "svg"); 

    // copy contents to native a static, array 
    svgs = Array.prototype.slice.call(svgs); 

    for (var i = 0; i < svgs.length; i++) 
    { 
     var e = document.createElementNS("http://www.w3.org/2000/svg", "svg"); 
     svgs[i].appendChild(e); 
    } 
} 

谢谢谢尔盖Ilinsky您的快速反应!

回答

1

您的问题的原因可能隐藏在由getElementByTagName(NS)方法调用返回的NodeSet的活性(例如querySelectorAll方法不是这种情况)中。因此,在你的代码中,你可以从SVG命名空间中找到名称为“svg”的所有元素,然后开始遍历这个列表,并向文档中添加新的“svg”元素,最后添加到你正在行走的集合中。绝妙的脚本根本不应该退出,但在实践中,当你看到浏览器崩溃时。

+0

你是对的。因为我错误地认为返回的'HTMLCollection'与原生JavaScript数组错误...感谢您的快速响应! – 2010-05-21 19:40:56