2010-05-21 90 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