Нужно ли удалять обработчики событий перед удалением элементов? - PullRequest
61 голосов
/ 17 мая 2011

Если у меня есть родительский элемент с дочерними элементами, к которым привязаны прослушиватели событий, нужно ли удалять эти прослушиватели событий перед тем, как очистить родительский элемент?(т. е. parent.innerHTML = '';). Может ли произойти утечка памяти, если прослушиватели событий не освобождаются от элемента, если он удален из DOM?

Ответы [ 2 ]

40 голосов
/ 08 мая 2016

Просто чтобы обновить информацию здесь.Я тестировал различные браузеры, особенно на предмет утечек памяти для циклически зависимых слушателей событий при событиях загрузки iframe.

Используемый код (jsfiddle мешает тестированию памяти, поэтому используйте свой собственный сервер для проверки этого):

<code><div>
    <label>
        <input id="eventListenerCheckbox" type="checkbox" /> Clear event listener when removing iframe
    </label>
    <div>
        <button id="startTestButton">Start Test</button>
    </div>
</div>

<div>
    <pre id="console">
(function () {var consoleElement = document.getElementById ('console'); window.log = function (text) {consoleElement.innerHTML = consoleElement.innerHTML + '
' +текст;};} ());(function () {function attachEvent (element, eventName, callback) {if (element.attachEvent) {element.attachEvent (eventName, callback);} еще {element [eventName] = callback;}} функция detachEvent (элемент, eventName,обратный вызов) {if (element.detachEvent) {element.detachEvent (eventName, callback);} else {element [eventName] = null;}} var eventListenerCheckbox = document.getElementById ('eventListenerCheckbox'); var startTestButton = document.getElementBI'startTestButton'); var iframe; var generateOnLoadEvent; функция createOnLoadFunction (iframe) {var obj = {increment: 0, огромныйMemory: new Array (100000) .join ('0') + (new Date (). getTime ()), roundReference: iframe}; return function () {// window.log ('вызывается загрузка iframe'); obj.increment + = 1; destroy ();};} функция create () {// window.log ('создать с именем '); iframe = document.createElement (' iframe '); generateOnLoadEvent = createOnLoadFunction (iframe); attachEvent (iframe,' onload ', generateOnLoadEvent); document.body.appendChild (IFrame);} function destroy () {// window.log ('destroy selected');if (eventListenerCheckbox.checked) {detachEvent (iframe, 'onload', generateOnLoadEvent)} document.body.removeChild (iframe);iframe = ноль;generateOnLoadEvent = null;} function startTest () {var interval = setInterval (function () {create ();}, 100);setTimeout (function () {clearInterval (interval); window.log ('test complete');}, 10000);} attachEvent (startTestButton, 'onclick', startTest);} ());

Если утечки памяти нет, используемая память увеличится примерно на 1000 КБ или менее после выполнения тестов.Однако при утечке памяти она увеличится примерно на 16 000 КБ.Первое удаление прослушивателя событий всегда приводит к меньшему использованию памяти (без утечек).

Результаты:

  • IE6 - утечка памяти
  • IE7 - утечка памяти
  • IE8 - утечка памяти
  • IE9 - утечка памяти (???)
  • IE10 - утечка памяти (???)
  • IE11 - утечка памяти
  • Edge (20) - без утечки памяти
  • Chrome (50) - без утечки памяти
  • Firefox (46) - сложно сказать, плохо течет, поэтому возможнопросто неэффективный сборщик мусора?Конец с дополнительными 4 МБ без видимой причины.
  • Opera (36) - без утечки памяти
  • Safari (9) - без утечки памяти

Вывод: Кровотечениеграничным приложениям, вероятно, не удастся удалить слушатели событий.Но я все равно считаю это хорошей практикой, несмотря на раздражение.

35 голосов
/ 17 мая 2011

Краткий ответ: да

Длинный ответ: большинство браузеров обрабатывают это правильно и сами удаляют эти обработчики. Есть некоторые старые браузеры (IE 6 и 7, если я правильно помню), которые портят это. Да, могут быть утечки памяти. Вам не нужно беспокоиться об этом, но вам нужно. Посмотрите этот документ .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...