Нужно ли удалять прослушиватели событий javascript перед удалением элемента, к которому они прикреплены?

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

необходимо (или предложено) отменить регистрацию любых обработчиков событий, которые существуют в форме и ее элементах? Если да, то каков самый простой способ удалить все прослушиватели в коллекции элементов? Каковы последствия отказа от этого? Я использую прототип, если это имеет значение.

вот что я на самом деле делаю. У меня простая форма, как это:

<form id="form">
  <input type="text" id="foo"/>
  <input type="text" id="bar"/>
</form>

Я наблюдаю различные события на входах, например:

$('foo').observe('keypress', onFooKeypress);
$('bar').observe('keypress', onBarKeypress);

etc.

форма отправляется через AJAX, и ответ представляет собой новую копию формы. Я заменяю старую форму копией новой, делая что-то вроде $('form').replace(newForm). Я накапливаю кучу событий?

3 ответов


да, немного. Недостаточно, чтобы быть огромной проблемой, но старые версии IE будут протекать в этих обстоятельствах.

начиная с прототипа 1.6.1 (в настоящее время в его последнем кандидате на выпуск) библиотека обрабатывает эту очистку на странице выгрузки. Когда вы используете Prototype для добавления наблюдателя событий, он сохраняет ссылку на этот элемент в массиве; на странице выгрузки он проходит через этот массив и удаляет все ваши наблюдатели.

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

  1. слушайте события на предка формы, которая никогда не заменяется. Затем в своем обработчике проверьте, откуда произошло событие. (т. е. "делегирование событий")

  2. явно отменить регистрацию всех вызовов перед вызовом Element#replace. В вашем примере вы бы сделали:

    $('foo', 'bar').each(Element.stopObserving);
    

Это эквивалентно зову stopObserving без аргументов, что имеет эффект удаления все обработчики для данного элемента.

Я бы рекомендовал Вариант 1.

(мы говорили о автоматическом удалении прослушивателя в будущей версии Prototype как части Element#update и Element#replace, но это компромисс производительности.)


события, которые не являются незарегистрированными, не могут автоматически освобождать память. Это особенно проблема в старых версиях IE.

прототип используется для автоматической системы сбора мусора для этого, но метод был удален в версии 1.6. Это документально здесь. Означает ли удаление метода, что сбор мусора больше не происходит, или метод просто больше не доступен для общественности, я не знаю. Также обратите внимание, что это было только когда-либо вызываемый на странице выгрузки, это означает, что если ваши пользователи остаются на одной странице в течение длительного времени, делая много обновлений AJAX и DOM, память может протекать в неприемлемой степени даже во время этого посещения одной страницы.


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