我正在尝试动态地附加一个 <svg>
元素到 XHTML 页面 (Firefox 3.6.3) 上的现有 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
的指针秒。示例:
function doesntCrash( )
{
var svg = document.getElementById( "mySVG" );
var e = document.createElementNS( "http://www.w3.org/2000/svg", "svg" );
svg.appendChild( e );
}
据我所知,这是一个 Firefox 错误。有没有人对此事有任何见解?
更新(解决方案):
如下所述,问题是 HTMLCollection
的“ active ”由 getElementsByTagNameNS
返回我误认为 native 数组的调用 (tsk, tsk!) 一个快速的变通方法是将数组长度存储在一个变量中,如果您只是追加的话。更好的解决方案可能是将数组内容复制到 native 数组,如所述 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 的快速回复!
最佳答案
问题的原因可能隐藏在 getElementByTagName(NS) 方法调用返回的 NodeSet 的 active 中(例如,querySelectorAll 方法不是这种情况)。因此,在您的代码中,您会从 SVG 命名空间中找到名称为“svg”的所有元素,然后开始遍历此列表并将新的“svg”元素添加到文档中,这些元素最终也会添加到您正在遍历的集合中。从理论上讲,脚本根本不应该退出,但实际上您会看到浏览器崩溃。
关于javascript - Firefox -- 在 SVG 中动态嵌入 <svg> 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2884838/