2010-02-21 2 views
43

Вопрос заключается в сравнении конкатенации с использованием innerHTML и добавлении текстового узла к существующему узлу. Что происходит за сценой?"innerHTML + = ..." vs "appendChild (txtNode)"

Мои мысли вокруг этого до сих пор:

  • Я предполагаю, что оба вызывает 'REflow'.
  • Последний (добавление текстового узла), из того, что я знаю, также вызывает полную перестройку DOM (правильно? Они оба это делают?).
  • У первого, похоже, есть другие неприятные побочные эффекты, например, вызывать ранее сохраненные ссылки на дочерние узлы на узел, который я изменяю innerHTML, чтобы больше не указывать на «текущую DOM»/«правильную версию дочернего узла», , Напротив, при добавлении детей ссылки, похоже, остаются нетронутыми. Почему это?

Я надеюсь, вы, люди, можете это очистить, спасибо!

ответ

69

Последний (appendChild) делает не вызывает полную перестройку DOM или даже всех элементов/узлов в пределах цели.

Бывший (установка innerHTML) действительно вызывает полную перестройку содержимого целевого элемента, который, если вы добавляете, не является необходимым.

Добавление через innerHTML += content позволяет обозревателю обойти все узлы в элементе, построив HTML-строку, чтобы передать слой JavaScript. Затем ваш код добавляет текст к нему и устанавливает innerHTML, в результате чего браузер удаляет все старые узлы в целевом объекте, повторно анализирует весь этот HTML и создает новые узлы. Поэтому в этом смысле это может быть неэффективно. (Тем не менее, анализ HTML является , что браузеры и они на самом деле, очень быстро на него.)

Установка innerHTML действительно аннулирует любые ссылки на элементы в целевом элементе может быть холдинг - потому что эти элементы донских 't существует больше, вы удалили их, а затем добавили новые (которые выглядели очень похожими), когда вы установили innerHTML.

Короче говоря, если вы добавления, я хотел бы использовать appendChild (или insertAdjacentHTML, смотри ниже). Если вы заменяете, есть очень правильные ситуации, когда использование innerHTML - лучший вариант, чем создание дерева через DOM API (скорость, являющаяся главным среди них).

Наконец, стоит упомянуть insertAdjacentHTML, что является функцией, которую вы можете использовать для вставки узлов и элементов в элемент или рядом с ним с помощью строки HTML. Вы можете добавить к нему элемент: theElement.insertAdjacentHTML("beforeend", "the HTML goes here"); Первым аргументом является размещение HTML; ваш выбор "beforebegin" (вне элемента, прямо перед ним), "afterbegin" (внутри элемента, в начале), "beforeend" (внутри элемента, в конце) и "afterend" (вне элемента, сразу после него) , Обратите внимание, что "afterbegin" и "beforeend" вставляются в сам элемент, тогда как "beforebegin" и "afterend" вставляют в элемент элемента. Поддерживается всеми основными браузерами для настольных компьютеров, я понятия не имею, насколько хороша мобильная поддержка (хотя я уверен, что iOS Safari и Android 2.x и, по крайней мере, имеют это), но the shim - крошечный.

+0

@TK: Как насчет поддержки браузера? Является ли один метод более вероятным, чем другой, для работы с более старыми и/или мобильными браузерами? – skaffman

+6

@ skaffman: В этот день и в возрасте, я ожидаю, что оба будут доступны в любом браузере, с которым вы работаете. 'innerHTML' является нестандартным, но почти универсальным (чтобы дать вам представление, как Prototype, так и jQuery полагаются на него). 'appendChild' является частью самого старого поколения уровней DOM, он будет там. :-) Обратите внимание, что существуют ограничения и причуды с 'innerHTML'. Например, вы не можете заменить строку таблицы, установив, например, элемент 'innerHTML' элемента TR в некоторых браузерах. IE будет лишать ведущее белое пространство, когда вы его используете. Элементы формы могут быть проблемой. И т. Д. –

+3

+1 от меня :-) Я бы сказал, если вы используете 'innerHTML', не используйте его внутри цикла. Это очень неэффективно, потому что вы запускаете парсер несколько раз. Я видел циклы типа 'for (var i = 0; i

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