2010-02-13 3 views
9

Какой метод ниже лучше всего подходит для пользователей?JavaScript: Добавление детей к элементу

В обоих примерах предположим, что 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?

ответ

6

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

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

Но, если вы хотите увеличить производительность, я бы предложил использовать DocumentFragments. Используя их, вы можете добавить целый набор узлов только одним вызовом appendChild в дереве документов. Стоит прочитать: "DOM DocumentFragments" by John Resig, но это не относится к вашей проблеме, потому что вы получаете контент как строку, которую вы должны сначала преобразовать в узлы 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; 
+0

Я бы ожидал, что ваш пример не сработает, так как 'Thumbnail # toXMLString' * возвращает строку с разметкой XHTML в ней *. Таким образом, предоставленное имя тега в 'document.createElement (htmlCode)' не является допустимым именем. – yckart

10

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

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

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

using appendChild?

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

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

для (вар ребенка в shell.childNodes) {

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

+2

+1, согласован со всеми пунктами (как обычно). –

+0

Спасибо за 'insertAdjacentHTML'. Вот что мне нужно – w35l3y

Смежные вопросы