我正在尝试动态地将<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错误。有没有人对此事有任何见解?
更新(解决方案):
如下所述,问题是HTMLCollection
调用返回的getElementsByTagNameNS
的“活跃度”,我误认为是原生数组( tsk,tsk!)快速解决如果你只是追加,那么将数组长度存储在一个变量中。更好的解决方案可能是将数组内容复制到本机数组,如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 );
}
}
谢谢Sergey Ilinsky的快速回复!
答案 0 :(得分:1)
您的问题的原因可能隐藏在getElementByTagName(NS)方法调用返回的NodeSet的活跃性中(例如,querySelectorAll方法不是这种情况)。因此,在您的代码中,您可以从SVG命名空间中找到名称为“svg”的所有元素,然后开始遍历此列表并将新的“svg”元素添加到文档中,最终添加到您正在处理的集合中。准确地说,脚本应该永远不会退出,但实际上你会看到浏览器崩溃。