removeEventListener() в JavaScript
Метод removeEventListener() удаляет обработчик, который раньше был добавлен через addEventListener(). Он нужен, когда обработчик должен работать только в определённый момент: пока открыта панель, идёт перетаскивание или включён режим редактирования.
Чтобы удалить обработчик, нужно обратиться к тому же элементу, указать тот же тип события и передать ту же функцию. Именно ссылка на функцию чаще всего становится причиной того, что обработчик остаётся на странице.
- Когда нужен removeEventListener()
- Синтаксис
- Пример с панелью настроек
- Нужна та же функция
- Параметр capture
- Итого
Когда нужен removeEventListener()
Не каждый обработчик нужно удалять вручную. Например, обработчик клика на постоянно видимой кнопке обычно нужен всё время, пока существует страница. Но обработчик на document или window часто должен работать только в одном состоянии интерфейса.
Если действие должно выполниться ровно один раз, можно добавить обработчик с опцией once. removeEventListener() используют, когда момент удаления определяется логикой программы: например, пользователь закрыл панель или отменил действие.
Синтаксис
target.removeEventListener(type, listener);
target.removeEventListener(type, listener, options);
target - тот же элемент, document или window, на котором был назначен обработчик. В type передают тип события, например ‘click’ или ‘keydown’, а в listener - функцию-обработчик.
Если подходящего обработчика нет, метод не выдаст ошибку и ничего не сделает. Поэтому отсутствие видимого результата обычно означает, что не совпал элемент, тип события, функция или параметр capture.
Пример с панелью настроек
Пусть клавиша Escape закрывает панель настроек только тогда, когда она открыта. Обработчик keydown добавляем при открытии панели и удаляем при закрытии.
<button class="open-settings" type="button">
Открыть настройки
</button>
<section class="settings-panel" hidden>
<p>Настройки открыты</p>
<button class="close-settings" type="button">
Закрыть
</button>
</section>
const openSettingsButton = document.querySelector('.open-settings');
const closeSettingsButton = document.querySelector('.close-settings');
const settingsPanel = document.querySelector('.settings-panel');
function closeSettings() {
settingsPanel.hidden = true;
document.removeEventListener('keydown', closeOnEscape);
}
function closeOnEscape(event) {
if (event.key === 'Escape') {
closeSettings();
}
}
openSettingsButton.addEventListener('click', function () {
settingsPanel.hidden = false;
document.addEventListener('keydown', closeOnEscape);
});
closeSettingsButton.addEventListener('click', closeSettings);
После открытия панели document начинает отслеживать нажатия клавиш. Если пользователь нажмёт Escape, вызовется closeSettings(): панель скроется, а обработчик closeOnEscape удалится.
Кнопка Закрыть вызывает ту же функцию closeSettings(), поэтому обработчик удаляется и при закрытии мышью. Когда панель скрыта, нажатие Escape больше не запускает этот код.
Нужна та же функция
Нельзя удалить обработчик, передав новую функцию с таким же содержимым. Каждое объявление функции создаёт отдельный объект, даже если код внутри совпадает.
<button class="save-button" type="button">
Сохранить
</button>
const saveButton = document.querySelector('.save-button');
saveButton.addEventListener('click', function () {
console.log('Сохранено');
});
saveButton.removeEventListener('click', function () {
console.log('Сохранено');
});
Во втором вызове передана другая функция, поэтому обработчик не удалится. Сохраните функцию в переменную или объявите её отдельно.
const saveButton = document.querySelector('.save-button');
function handleSave() {
console.log('Сохранено');
}
saveButton.addEventListener('click', handleSave);
saveButton.removeEventListener('click', handleSave);
Анонимную стрелочную функцию тоже можно удалить, если сохранить её в переменную: const handleSave = () => { … }. Важно передать в оба метода одну и ту же ссылку, а не написать функцию заново.
Параметр capture
При удалении должен совпадать и параметр capture. Он определяет, назначен ли обработчик на этапе перехвата. Если третий аргумент не указан, используется значение false.
function handleClick() {
console.log('Клик');
}
document.addEventListener('click', handleClick, true);
document.removeEventListener('click', handleClick, true);
Если во втором вызове не передать true, обработчик останется. Один и тот же обработчик можно добавить с capture, равным true и false, но удалить такие варианты нужно отдельно.
Параметры once и passive не участвуют в поиске обработчика для удаления. Но если в коде используется объект с опциями, проще передавать одинаковое значение capture в обоих вызовах.
Итого
removeEventListener() снимает обработчик в момент, который определяет ваш код. Для этого нужны тот же объект, тип события, ссылка на функцию и значение capture. Храните обработчики в именованных функциях или переменных, если планируете удалить их позже.