【问题标题】:Firefox -- Dynamically embedding <svg> element in SVGFirefox -- 在 SVG 中动态嵌入 <svg> 元素
【发布时间】:2010-05-22 03:53:25
【问题描述】:

我正在尝试动态地将 &lt;svg&gt; 元素附加到 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,它会工作很好。有趣,但在我的情况下并不是特别有用,因为我正在存储指向SVGDocuments 的指针。示例:

function doesntCrash( )
{
    var svg = document.getElementById( "mySVG" );
    var e = document.createElementNS( "http://www.w3.org/2000/svg", "svg" );
    svg.appendChild( e );
}

据我所知,这是一个 Firefox 错误。 有没有人对此有任何见解?

已更新(解决方案): 如下所述,问题在于 getElementsByTagNameNS 调用返回的 HTMLCollection 的“活跃性”,我将其误认为是原生数组(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 的快速回复!

【问题讨论】:

    标签: javascript firefox svg


    【解决方案1】:

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

    【讨论】:

    • 你说得对。真不好意思将返回的 HTMLCollection 误认为是原生 JavaScript 数组...感谢您的快速回复!
    猜你喜欢
    • 2011-09-26
    • 1970-01-01
    • 2021-08-03
    • 2016-10-18
    • 1970-01-01
    • 2011-12-23
    • 2011-07-23
    • 2012-09-14
    • 2013-10-30
    相关资源
    最近更新 更多