JavaScript: добавление дочерних элементов к элементу - PullRequest
9 голосов
/ 13 февраля 2010

Какая методика ниже лучше из опыта пользователя?

В обоих примерах предположим, что для thumbContainer установлено возвращаемое значение document.getElementById('thumbContainer'), а new Thumbnail(thumb).toXMLString() возвращает строку с разметкой XHTML.

A) Просто += с thumbContainer.innerHTML:

for (thumb in thumbnails) {
    thumbContainer.innerHTML += new Thumbnail(thumb).toXMLString();
} 

B) Или преобразование new Thumbnail(thumb).toXMLString() в DOM-элементы и использование appendChild?

for (thumb in thumbnails) {
    var shell = document.createElement('div');
    shell.innerHTML = new Thumbnail(thumb).toXMLString();
    for (i = 0; i < shell.childElementCount; i++) {
        thumbContainer.appendChild(shell.children[i]);
    }
}

Я использовал оба и получаю жалобы от Firefox, что у меня есть долгосрочный скрипт, и хочу ли я его остановить?

Какой цикл менее плотный, что позволит обновлять интерфейс при добавлении новых элементов в DOM?

Ответы [ 2 ]

10 голосов
/ 13 февраля 2010

A) Просто + = с помощью thumbContainer.innerHTML

Никогда не делайте этого. Это должно сериализовать весь контент в HTML, добавить строку и проанализировать все обратно. Это медленно (делать это в цикле - особенно плохие новости), и он потеряет все ссылки JavaScript, обработчики событий и т. Д. .

IE insertAdjacentHTML сделает это более эффективно. Он также является частью HTML5, но пока еще не получил широкого распространения.

используя appendChild?

Да, все в порядке. Если у вас есть много больших пальцев, он начнет работать медленнее (но не так плохо, как повторная обработка innerHTML каждый раз). Создание DocumentFragment для вставки нескольких элементов в список дочерних узлов контейнера может помочь в некоторых случаях. Комбинация DocumentFragment с Range может сделать еще больше, но становится труднее писать совместимо, так как реализация Range в IE так StRange.

В любом случае, поскольку вы, похоже, ничего не делаете с отдельными узлами оболочки, почему бы просто не объединить все миниатюрные HTML-строки перед анализом?

для (var child в shell.childNodes) {

Не используйте for..in для типов последовательности, это не будет делать то, что вы думаете. Он предназначен только для использования против Object, используемого в качестве отображения. Правильный способ перебора массива или NodeList - старый for (var i= 0; i<sequence.length; i++).

6 голосов
/ 13 февраля 2010

Лично мне больше нравится второй подход (использующий appendChild), потому что вы добавляете новый элемент в дерево документа, не затрагивая старые элементы.

При использовании innerHTML + = new content вы воздействуете на старый контент, потому что весь HTML должен быть переназначен (заменен новым HTML, который содержит старый код и некоторый новый код).

Но, если вы хотите повысить производительность, я бы предложил использовать DocumentFragments. Используя их, вы можете добавить целый набор узлов с помощью всего одного вызова appendChild в дереве документа. Стоит прочесть: «DOM DocumentFragments» Джона Резига , но это не та проблема, которая возникает в вашей задаче, потому что вы получаете содержимое в виде строки, которую необходимо сначала преобразовать в узлы DOM.

Мое второе предложение - создать строку HTML-кода, а затем использовать innerHTML во временном контейнере для преобразования его в узлы DOM

var htmlCode = "";
for (thumb in thumbnails) {
    htmlCode += new Thumbnail(thumb).toXMLString();
}
var element = document.createElement(htmlCode);
element.innerHTML = htmlCode; // ... and append all the elements to document, or thumbContainer.innerHTML += htmlCode;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...