Подтвердить что ты не робот

Является ли обработчик событий javascript в памяти даже после удаления элемента DOM, к которому он привязан?

Учитывая следующий код

<div id="app">
  <div id="foo" />
</div>

<script>
  $('#foo').bind('click', function(){});
</script>

Я планирую заменить содержимое #app [например. $('#app').html('...');, или innerHTML = '...';]. Я знаю, что я могу использовать jQuery .remove(), который вызывает обработчик 'destroy', который отвязывает события. Тот факт, что есть обработчик destroy, настроенный для удаления событий, приводит меня к мысли, что без открепления событий, когда элемент DOM будет удален, обработчик все еще будет существовать в памяти.

Итак, если элемент DOM #foo больше не существует, исчезает ли обработчик или он теряется в памяти браузера?

4b9b3361

Ответ 1

jQuery отслеживает сам обработчик событий, который является частью того, почему вам нужно использовать unbind (в настоящее время он off) если вы удаляете элемент из DOM не с помощью метода jQuery (если вы используете jQuery empty или remove, как вы упомянули, это само по себе само по себе). Это значит, что jQuery знает, что он может освободить ссылку на обработчик.

Если бы это было не так, тогда теоретически вам не пришлось бы ничего делать, потому что, как только элемент DOM будет удален из памяти, он больше не будет доступен, и поэтому теоретически не следует сохранять обработчик событий в Память. Это теория. Реальность очень различна, может быть очень легко закончить ситуацию (особенно в IE), где ни элемент DOM, ни обработчик событий не могут быть очищены, потому что каждый из них заставляет другого придерживаться — утечка памяти. JavaScript не имеет проблем с круговыми ссылками (он их понимает и может выпускать две вещи, которые указывают друг на друга, если ничто другое не указывает на них), но часть DOM в браузере, вероятно, будет написана на другом языке с другой механизм сбора мусора (IE использует COM, который использует подсчет ссылок, а не достижимость). jQuery помогает избежать этой ловушки с IE (часть того, почему она отслеживает обработчики событий), но вы должны использовать unbind (в настоящее время off) (или удалить элементы через empty, remove и т.д.). как следствие.

Извлеките сообщение: как вы зацепите, так и вы отцепите.:-) (И/или использовать jQuery при удалении элементов, поскольку он будет обрабатывать это.)

В некоторой степени: если вы много добавляете и удаляете элементы, вы можете посмотреть, происходит ли делегирование событий (что jQuery делает очень легко через сигнатуры делегирования для on).

Ответ 2

Просто случилось читать документы по jQuery empty() метод:

Чтобы избежать утечек памяти, jQuery удаляет другие конструкции, такие как данные и обработчики событий из дочерних элементов перед удалением элементов сами по себе.