Firefox -- SVG中动态嵌入<svg>元素

3

我正在尝试动态地将一个<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的快速回复!
1个回答

1
你遇到的问题可能是由于 getElementByTagName(NS) 方法返回的 NodeSet 的存活性导致的(例如,querySelectorAll 方法不会出现这种情况)。因此,在你的代码中,你找到所有 SVG 命名空间中名称为 "svg" 的元素,然后开始遍历此列表并向文档添加新的 "svg" 元素,最终被添加到你正在遍历的集合中。理论上脚本应该永远不会退出,但实际上,如你所见,浏览器会崩溃。

你说得完全正确。我错把返回的 HTMLCollection 和原生的 JavaScript 数组混淆了... 谢谢你的快速回复! - Courtney Christensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接