Firefox - Динамически встраивая элемент <svg>в SVG - PullRequest
3 голосов
/ 21 мая 2010

Я пытаюсь динамически добавить элемент <svg> к существующему островку SVG на странице XHTML (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 s.Пример:

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! )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 );
    }
}

Спасибо, Сергей Ильинский, за быстрый ответ!

1 Ответ

1 голос
/ 21 мая 2010

Причина вашей проблемы, вероятно, скрыта в жизнеспособности NodeSet, возвращаемого вызовом метода getElementByTagName (NS) (что, например, не относится к методу querySelectorAll). Таким образом, в вашем коде вы найдете все элементы с именем "svg" из пространства имен SVG, затем начнете проходить по этому списку и добавите новые элементы "svg" в документ, которые в конечном итоге будут добавлены в коллекцию, которую вы также просматриваете. Теоретически скрипт никогда не должен завершаться, но на практике, как вы видите, происходит сбой браузера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...