我正在尝试动态地将一个<svg>
元素附加到现有的XHTML页面上的SVG区域(Firefox 3.6.3)。但是这会导致浏览器崩溃。
如果手动完成,它可以正常工作:
<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
的指针。例如: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方法是,如果你只是追加,可以将数组长度存储在变量中。更好的解决方案可能是将数组内容复制到本地数组中,如此处所述。以下是使用该方法进行更新的内容:
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 );
}
}
感谢Sergey Ilinsky的快速回复!
HTMLCollection
和原生的 JavaScript 数组混淆了... 谢谢你的快速回复! - Courtney Christensen