Слушатели события JavaScript должны быть удалены до удаления элемента, к которому они присоединены?

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

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

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

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

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

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

и т.д.

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

8
задан Brian Tompsett - 汤莱恩 21 July 2019 в 18:03
поделиться

3 ответа

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

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

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

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

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

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

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

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

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

3
ответ дан 5 December 2019 в 21:21
поделиться

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

0
ответ дан 5 December 2019 в 21:21
поделиться

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

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

4
ответ дан 5 December 2019 в 21:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: