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

时间:2010-05-21 19:07:50

标签: javascript firefox svg

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

1 个答案:

答案 0 :(得分:1)

您的问题的原因可能隐藏在getElementByTagName(NS)方法调用返回的NodeSet的活跃性中(例如,querySelectorAll方法不是这种情况)。因此,在您的代码中,您可以从SVG命名空间中找到名称为“svg”的所有元素,然后开始遍历此列表并将新的“svg”元素添加到文档中,最终添加到您正在处理的集合中。准确地说,脚本应该永远不会退出,但实际上你会看到浏览器崩溃。