Что лучше, добавление новых элементов через функции DOM или добавление строк с тегами HTML?
Я добавил несколько разных способов добавления элементов в DOM. Наиболее предсказуемым представляется, например, либо
document.getElementById('foo').innerHTML ='<p>Here is a brand new paragraph!</p>';
или
newElement = document.createElement('p');
elementText = document.createTextNode('Here is a brand new parahraph!');
newElement.appendChild(elementText);
document.getElementById('foo').appendChild(newElement);
но я не уверен в преимуществах одного. Есть ли правило большого пальца о том, когда нужно делать над другим, или один из них просто ошибочен?
Ответы
Ответ 1
Некоторые примечания:
-
Использование innerHTML
выполняется быстрее в IE, но медленнее в chrome + firefox. Здесь один тест, показывающий это с постоянно меняющимся набором <div>
+ <p>
s; здесь эталонный показатель, показывающий это для постоянного, простого <table>
.
-
С другой стороны, методы DOM являются традиционным стандартом - innerHTML
стандартизируется в HTML5 - и позволяет вам сохранять ссылки на вновь созданные элементы, чтобы впоследствии вы могли их модифицировать.
-
Потому что innerHTML быстрый (достаточно), лаконичный и простой в использовании, заманчиво опираясь на него для каждой ситуации. Но будьте осторожны, что использование innerHTML
отделяет все существующие узлы DOM от документа. Вот пример, который вы можете проверить на этой странице.
Сначала создайте функцию, которая позволяет нам проверить, есть ли node на странице:
function contains(parent, descendant) {
return Boolean(parent.compareDocumentPosition(descendant) & 16);
}
Это вернет true
, если parent
содержит descendant
. Проверьте это следующим образом:
var p = document.getElementById("portalLink")
console.log(contains(document, p)); // true
document.body.innerHTML += "<p>It clobberin' time!</p>";
console.log(contains(document, p)); // false
p = document.getElementById("portalLink")
console.log(contains(document, p)); // true
Это напечатает:
true
false
true
Может показаться, что наше использование innerHTML
должно было повлиять на нашу ссылку на элемент portalLink
, но это так. Его необходимо снова найти для правильного использования.
Ответ 2
Существует несколько отличий:
-
innerHTML
стандартизирован только W3C для HTML 5; даже несмотря на то, что в течение некоторого времени он был стандартом де-факто во всех популярных браузерах, технически в HTML 4 это расширение для поставщиков, которое разработчики, придерживающиеся стандартов, никогда не будут пойманы мертвыми. С другой стороны, это гораздо удобнее и практически поддерживается всеми браузерами.
-
innerHTML
заменяет текущее содержимое элемента (он не позволяет вам его изменять). Но опять же, вы получаете удобство, если не возражаете против этого ограничения.
-
innerHTML
было измерено, чтобы быть намного быстрее (по общему признанию, этот тест включает браузеры старых версий, которые сегодня широко не используются).
-
innerHTML
может представлять угрозу безопасности (XSS), если он настроен на предоставленное пользователем значение, которое не было правильно закодировано (например, el.innerHTML = '<script>...'
).
Исходя из вышесказанного, кажется, что практический вывод может быть:
- Если вы не возражаете против того, что
innerHTML
является битовым ограничением (только полная замена поддерева DOM, внедренного в целевой элемент), и вы не рискуете своей уязвимостью путем инъекции контента, предоставляемого пользователем, используйте, В противном случае перейдите в DOM.
Ответ 3
В соответствии с эти контрольные данные, вы получите гораздо более быстрые результаты с innerHTML
, чем создание элементов DOM. Это особенно заметно при использовании старых версий IE.
Ответ 4
Первый из них прямолинейный, легче читать, меньше кода и может быть быстрее.
Во-вторых, вы получаете гораздо больший контроль над создаваемым элементом, т.е. Значительно облегчает изменение нового элемента с помощью JS (например, прикрепление событий или просто использование его в вашем коде).
Второй способ - "пурист", которому нравится "чистый" код (не быстро и грязно).
Я говорю: используйте оба варианта, посмотрите, что вам лучше подходит и пойдет с ним.
Ответ 5
Я всегда предпочитаю читаемость, если разница между первыми не является экстремальной. В одноразовом случае это, вероятно, будет незначительной разницей.
В одноразовом случае, как правило, установить свойство innerHTML
будет легче всего читать.
Но если вы делаете много программного контента в JavaScript, он чище и проще читать и понимать параметр DOM.
Пример:
Сравните этот код innerHTML
:
http://jsfiddle.net/P8m3K/1/
// Takes input of a value between 1 and 26, inclusive,
// and converts it to the appropriate character
function alphaToChar(alpha)
{
return String.fromCharCode('a'.charCodeAt() + alpha - 1);
}
var content = "<ul>";
for(i = 0; i < 10; ++i)
{
content += "<li>";
for(j = 1; j <= 26; ++j)
{
content += "<a href=\"" + alphaToChar(j) + ".html\">"
+ alphaToChar(j)
+ "</a>";
}
content += "</li>";
}
document.getElementById("foo").innerHTML = content;
К этому коду DOM:
http://jsfiddle.net/q6GB8/1/
// Takes input of a value between 1 and 26, inclusive,
// and converts it to the appropriate character
function alphaToChar(alpha)
{
return String.fromCharCode('a'.charCodeAt() + alpha - 1);
}
var list = document.createElement("ul");
for(i = 0; i < 10; ++i)
{
var item = document.createElement("li");
for(j = 1; j <= 26; ++j)
{
var link = document.createElement("a");
link.setAttribute("href", alphaToChar(j) + ".html");
link.innerText = alphaToChar(j);
item.appendChild(link);
}
list.appendChild(item);
}
document.getElementById("foo").appendChild(list);
На этом уровне они начинают становиться очень похожими по длине.
Но код DOM будет проще в обслуживании, и вы немного реже делаете опечатку или ошибку, которую трудно диагностировать, например, опустить закрывающий тег. Либо ваши элементы будут в вашем документе, либо они не будут.
- С более сложными сценариями (например, с помощью встроенных меню) вы, вероятно, выйдете с кодом DOM.
- С сценариями, в которых вам нужно добавлять несколько типов контента для создания документа с более разнородным контентом, он становится slam dunk. Вам не нужно, чтобы вы вызывали код вашего дочернего кода перед вызовом родительского кода добавления.
- В сценариях, где добавляются, удаляются или изменяются существующие статические данные, DOM обычно выигрывает.
Если вы начнете выполнять сложные модификации DOM (одна из последних вещей, о которых я упоминал), вы обязательно захотите проверить библиотеку, построенную вокруг модификаций DOM, как jQuery.