Нужно ли удалять прослушиватели событий 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 для добавления наблюдателя событий, он сохраняет ссылку на этот элемент в массиве; на странице выгрузки он проходит через этот массив и удаляет все ваши наблюдатели.
однако, если пользователь хочет остаться на этой странице в то время как использование памяти будет накапливаться в течение жизни страницы. У вас есть несколько вариантов:
слушайте события на предка формы, которая никогда не заменяется. Затем в своем обработчике проверьте, откуда произошло событие. (т. е. "делегирование событий")
-
явно отменить регистрацию всех вызовов перед вызовом
Element#replace
. В вашем примере вы бы сделали:$('foo', 'bar').each(Element.stopObserving);
Это эквивалентно зову stopObserving
без аргументов, что имеет эффект удаления все обработчики для данного элемента.
Я бы рекомендовал Вариант 1.
(мы говорили о автоматическом удалении прослушивателя в будущей версии Prototype как части Element#update
и Element#replace
, но это компромисс производительности.)
события, которые не являются незарегистрированными, не могут автоматически освобождать память. Это особенно проблема в старых версиях IE.
прототип используется для автоматической системы сбора мусора для этого, но метод был удален в версии 1.6. Это документально здесь. Означает ли удаление метода, что сбор мусора больше не происходит, или метод просто больше не доступен для общественности, я не знаю. Также обратите внимание, что это было только когда-либо вызываемый на странице выгрузки, это означает, что если ваши пользователи остаются на одной странице в течение длительного времени, делая много обновлений AJAX и DOM, память может протекать в неприемлемой степени даже во время этого посещения одной страницы.
всегда полезно удалить любые прослушиватели событий из элементов, которые удаляются из DOM в случае сценария, упомянутого ниже.