2015-01-27 4 views
0

Я просто открываю этот удивительный метод элементов HTML DOM, innerHTML.Позволяет ли присваивать innerHTML удалить HTML-поддерево?

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

var removeChildNodes = function(node) { 
    while (node.firstChild) { 
    node.removeChild(node.firstChild); 
    } 
}; 

var dynamicContentNode = document.getElementById('dynamic-content'); 

// Is this step important? 
removeChildNodes(dynamicContentNode); 

// (Recursively?) Populate the new subtree of HTML DOM elements 
dynamicContentNode.innerHtml = '<div><p>Oh hai</p></div>'; 
+3

Чтобы добавить @ ответ Бьерна: Это ужасная идея, чтобы удалить детей во-первых, потому что каждое такое действие вызывает перерисовку в браузере, что делает ваш интерфейс слабым. Вы теряете всю скорость в этом действии, что настройка 'innerHTML' получает прямо. – Boldewyn

+0

Теперь, когда вы это узнали, я рекомендую использовать его только при необходимости (например, ответ Ajax). DOM-манипуляция в качестве объектов предпочтительнее, потому что чередование с HTML-строками может быть беспорядочным/подверженным ошибкам. Кроме того, если вы имеете дело с созданием кода на стороне сервера (например, JSP, PHP, ASP, ...), я рекомендую генерировать код на стороне сервера, избегая создания JS DOM (на стороне клиента). –

ответ

3

innerHTML полностью заменяет элементы HTML для элемента. Их просто удаляют, а мусор собирает браузер. Вам не нужно сначала удалять дочерние элементы. Поддерево исчезло.

+0

Можете ли вы ссылаться на свои претензии в отношении сбора мусора? – Nit

+0

Мне интересно, кто разобрал -1 ... – Boldewyn

+1

@Nit, вы можете увидеть сборку мусора в действии в профилировщике веб-инспектора Chrome. Записывайте распределения кучи с течением времени, а затем добавляйте и удаляйте элементы с помощью 'innerHTML' –

0

Это интересно. Я предполагаю, что querySelector возвращает узел ссылка - иначе как вы могли бы использовать его для управления узлом?

Поэтому я ожидаю, что приведенный ниже код будет предупреждать «Это тест», а затем выбросить ошибку, поскольку переменная span больше не указывает на узел.

Предупреждения IE «Это тест», а затем он уведомляет пустую строку.

Все другие браузеры предупреждение «Это тест» для обоих предупреждений. Как будто сбор мусора не происходит.

Обновление: В случае, если сбор мусора удаленного узла DOM возникает, когда не было ссылок на узел, я помещаю querySelector в функцию. Если сборка мусора происходит во время простоя, я ставлю второе предупреждение внутри setTimeout. В setTimeout, переменная span по-прежнему определяется, но я удивлен, что узел он ссылается еще существует:

function test() { 
 
    var span= document.querySelector('span'); 
 
    alert(span.innerHTML); 
 
    document.querySelector('div').innerHTML= 'Bye, bye'; 
 
    setTimeout(function() { 
 
    alert(span.innerHTML); 
 
    },100); 
 
} 
 

 
test();
<div id="D"> 
 
    <span>This is a test</span> 
 
</div>

+0

Я предполагаю, что это связано с тем, что каждый документ работает в одном потоке, а выполнение JavaScript предотвращает фактическое обновление документа во время работы скрипта. Вот почему вы можете заблокировать пользовательский интерфейс для веб-страницы с длинным сценарием. Все клики перестают отвечать, прокрутка заблокирована, вся страница заблокирована. –

+0

Я также предполагаю, что IE обновляет свое состояние внутри innerHTML, хотя и не является фактической страницей, и что другие браузеры, такие как Chrome, планируют оповещение со старым состоянием, а затем дают возможность браузеру обновляться до того, как на самом деле срабатывает предупреждение. должны посмотреть на код браузера, чтобы убедиться, что это действительно так. Меня это не удивило бы, если бы это было так. –

+0

Я рассмотрел эти возможности, и, думаю, я обратился к ним в своем обновлении. Возможно, вызов 'querySelector' на узле запрещает сборку мусора на этом узле. –

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