.remove Event Listener ( )
Удаляет обработчик события с элемента, установленный с помощью add Event Listener ( ) .
Как пишется
Скопировать ссылку «Как пишется» Скопировано
Добавим обработчик на элемент, а затем удалим его.
Например, будем обрабатывать клики на любое место на странице, а затем удалим обработчик, передав в remove Event Listener ( ) те же аргументы, что и при добавлении:
function handleMouseClick(event) console.log('Вы нажали на элемент:', event.target)> // Добавляем обработчик событияwindow.addEventListener('click', handleMouseClick) // Убираем обработчик событияwindow.removeEventListener('click', handleMouseClick)
function handleMouseClick(event) console.log('Вы нажали на элемент:', event.target) > // Добавляем обработчик события window.addEventListener('click', handleMouseClick) // Убираем обработчик события window.removeEventListener('click', handleMouseClick)
Метод remove Event Listener ( ) принимает три аргумента. Первые два обязательные:
- название события строкой;
- функция-обработчик, которую нужно убрать с указанного события.
Третий аргумент необязательный — это объект с настройками в котором могут содержаться свойства capture и passive с булевыми значениями true либо false . Точно такие же опции, можно передать и в .add Event Listener ( ) .
window.addEventListener('click', handleMouseClick, capture: true, passive: true>) // Аналогичные опции при удалении обработчикаwindow.removeEventListener('click', handleMouseClick, capture: true, passive: true>)
window.addEventListener('click', handleMouseClick, capture: true, passive: true >) // Аналогичные опции при удалении обработчика window.removeEventListener('click', handleMouseClick, capture: true, passive: true >)
Переданные настройки влияют на удаление обработчика события. Мы рекомендуем повторять в точности те же параметры, которые использовались в .add Event Listener ( ) , чтобы браузер точно знал какой обработчик нужно удалить.
Например, создадим обработчик события и передадим третьим аргументом в опциях значение true . Если попробовать убрать событие, но ничего не передать в опциях в .remove Event Listener ( ) , то событие не уберётся.
function handleMouseClick(event) console.log('Вы нажали на элемент:', event.target)> window.addEventListener('click', handleMouseClick, true) // Ничего не передаем в опциях в третьем аргументеwindow.removeEventListener('click', handleMouseClick)
function handleMouseClick(event) console.log('Вы нажали на элемент:', event.target) > window.addEventListener('click', handleMouseClick, true) // Ничего не передаем в опциях в третьем аргументе window.removeEventListener('click', handleMouseClick)
Аналогичная ситуация, если делать наоборот.
Как понять
Скопировать ссылку «Как понять» Скопировано
Браузер даёт возможность не только устанавливать обработчик события, но и убирать их.
Очищать обработчики событий важно, потому что каждый обработчик занимает место в памяти и выполняется всякий раз, когда срабатывает событие. Если не убирать неиспользуемые обработчики событий, то можно столкнуться с неожиданным поведением. Например, один из старых обработчиков будет мешать всплытию события наверх, и другой обработчик не будет работать.
Хорошим тоном считается убирать обработчик сразу же, как он перестал быть нужен.
Будет ли на самом деле удалён обработчик события зависит от того, какую функцию и какие опции передали вторым и третьим аргументами в .remove Event Listener ( ) .
Функции относятся к ссылочным типам данных, а значит две одинаково написанные функции будут считаться различными. Поэтому, если ранее в .add Event Listener ( ) использовалась анонимная функция, то убрать обработчик с помощью .remove Event Listener ( ) не получится.
window.addEventListener('click', (event) => console.log('Клик!')>) // Обработчик не будет удалён!window.removeEventListener('click', (event) => console.log('Клик!')>)
window.addEventListener('click', (event) => console.log('Клик!') >) // Обработчик не будет удалён! window.removeEventListener('click', (event) => console.log('Клик!') >)
Всегда сохраняйте функцию-обработчик в переменную чтобы позже убрать обработчик. Делать это необязательно только если вы делаете быстрый прототип или проверяете свою идею прямо в браузере.
Браузер сравнивает опции, когда ищет обработчик события для удаления. Посмотрим ещё раз на пример выше, когда в .add Event Listener ( ) передали в опциях true , а в .remove Event Listener ( ) нет опций.
function handleMouseClick(event) console.log('Вы нажали на элемент:', event.target)> window.addEventListener('click', handleMouseClick, true) // Обработчик не удалится, потому что опции не совпадаютwindow.removeEventListener('click', handleMouseClick)
function handleMouseClick(event) console.log('Вы нажали на элемент:', event.target) > window.addEventListener('click', handleMouseClick, true) // Обработчик не удалится, потому что опции не совпадают window.removeEventListener('click', handleMouseClick)
Так происходит потому что третий аргумент неявно устанавливается в undefined , а undefined превращается в false при конвертации в булевый тип. Когда браузер ищет обработчик на удаление, он сравнивает опции и видит, что true ! = = false , значит обработчик не будет удалён.
На практике
Скопировать ссылку «На практике» Скопировано
Егор Огарков советует
Скопировать ссылку «Егор Огарков советует» Скопировано
Автоматическое очищение обработчика после первого срабатывания
Если нужно чтобы событие сработало только один раз, то можно не использовать remove Event Listener ( ) , а использовать опцию once в add Event Listener ( ) .
window.addEventListener('click', function (event) console.log('Клик!')>, < once: true >)
window.addEventListener('click', function (event) console.log('Клик!') >, once: true >)
При первом клике обработчик сработает, а затем автоматически удалится. В этом случае можно даже использовать анонимную функцию, так как не нужно очищать обработчик вручную.
Можно написать очищение обработчика в самом обработчике событий
Когда в браузерах не было возможности использовать опцию < once : true >при установке обработчика события, такое поведение делали самостоятельно:
function handleClick(event) console.log('Клик!') // Сразу же очищаем после вызова функции, // обработчик сработает только один раз window.removeEventListener('click', handleClick)> window.addEventListener('click', handleClick)
function handleClick(event) console.log('Клик!') // Сразу же очищаем после вызова функции, // обработчик сработает только один раз window.removeEventListener('click', handleClick) > window.addEventListener('click', handleClick)
Другим примером может быть очищение обработчика по определённому условию. Добавим обработчик события клавиатуры, но по нажатию клавиши Esc будет очищать его.
function handleKeypress(event) console.log('Нажата клавиша:', event.key) if (event.key === 'Escape') window.removeEventListener('keypress', handleKeypress) >> window.addEventListener('keypress', handleKeypress)
function handleKeypress(event) console.log('Нажата клавиша:', event.key) if (event.key === 'Escape') window.removeEventListener('keypress', handleKeypress) > > window.addEventListener('keypress', handleKeypress)
Метод EventTarget.removeEventListener()
Удаляет обработчик события, который был зарегистрирован при помощи EventTarget.addEventListener() . Обработчик определяется типом события, самой функцией обработки события, и дополнительными параметрами, переданными при регистрации обработчика.
Синтаксис
target.removeEventListener(type, listener[, options]); target.removeEventListener(type, listener[, useCapture]);
Параметры
Строка, описывающая тип события, которое нужно удалить.
EventListener функция, которую нужно удалить с элемента.
Объект опций, описывающий характеристики обработчика события. Доступные опции:
- capture : Boolean . Указывает на то, что события этого типа отправляются данному обработчику до того, как происходит их передача любым EventTarget , находящимся ниже него в дереве DOM.
- passive : Boolean . Указывает на то, что listener никогда не будет вызывать preventDefault() . В противном случае (если listener вызовет preventDefault() ), user agent проигнорирует вызов и сгенерирует предупреждение в консоли.
Указывает, был ли удаляемый EventListener зарегистрирован как перехватывающий обработчик, или нет. Если этот параметр отсутствует, предполагается значение по умолчанию: false .
Если обработчик был зарегистрирован дважды, один раз с перехватом (с capture ) и один — без, каждый из них должен быть удалён по отдельности. Удаление перехватывающего обработчика никак не затрагивает неперехватывающую версию этого же обработчика, и наоборот.
Примечание: useCapture требуется в большинстве основных браузеров старых версий. Если вы хотите поддерживать большую совместимость, вы всегда должны использовать параметр useCapture .
Возвращаемое значение
Поиск обработчика при удалении
В большинстве браузеров помимо типа события и функции важно лишь совпадение значений параметра useCapture / options.capture , но так как это поведение не закреплено стандартом, наилучшим способом будет указание для removeEventListener() в точности тех же параметров, что были переданы в addEventListener() .
Примечания
Если EventListener был удалён из EventTarget в процессе обработки события (например предшествующим EventListener того же типа), он не будет вызван. После удаления, EventListener не будет вызываться, однако его можно назначить заново.
Вызов removeEventListener() с параметрами, не соответствующими ни одному зарегистрированному EventListener в EventTarget , не имеет никакого эффекта.
Пример
Это пример добавления и последующего удаления обработчика событий.
var div = document.getElementById("div"); var listener = function (event) /* do something here */ >; div.addEventListener("click", listener, false); div.removeEventListener("click", listener, false);
Совместимость браузеров
BCD tables only load in the browser
Gecko примечания
- В версиях Firefox младше версии 6 браузер бросает исключение, если параметр useCapture не был явно указан как false. В Gecko младше 9.0, addEventListener() бросает исключение, если параметр listener равен null ; в настоящее время метод отрабатывает без ошибки, но при этом не производит никаких действий.
Opera примечания
- В Opera 12.00 параметр useCapture — опциональный (source).
WebKit примечания
- Несмотря на то, что WebKit явно добавил » [optional] » к параметру useCapture в Safari 5.1 и Chrome 13, это работало и до изменений.
Спецификация
Полифилы для поддержки старых браузеров
addEventListener() и removeEventListener() отсутствуют в старых браузерах. Это ограничение можно обойти, вставив следующий код в начале ваших скриптов, что позволяет использовать addEventListener() и removeEventListener() в версиях, не поддерживающих эти методы нативно. Тем не менее, этот метод не работает в Internet Explorer версии 7 и ниже, так как расширение Element.prototype не поддерживалось в более ранних версиях Internet Explorer ранее 8.
if (!Element.prototype.addEventListener) var oListeners = >; function runListeners(oEvent) if (!oEvent) oEvent = window.event; > for ( var iLstId = 0, iElId = 0, oEvtListeners = oListeners[oEvent.type]; iElId oEvtListeners.aEls.length; iElId++ ) if (oEvtListeners.aEls[iElId] === this) for (iLstId; iLstId oEvtListeners.aEvts[iElId].length; iLstId++) oEvtListeners.aEvts[iElId][iLstId].call(this, oEvent); > break; > > > Element.prototype.addEventListener = function ( sEventType, fListener /*, useCapture (will be ignored!) */, ) if (oListeners.hasOwnProperty(sEventType)) var oEvtListeners = oListeners[sEventType]; for ( var nElIdx = -1, iElId = 0; iElId oEvtListeners.aEls.length; iElId++ ) if (oEvtListeners.aEls[iElId] === this) nElIdx = iElId; break; > > if (nElIdx === -1) oEvtListeners.aEls.push(this); oEvtListeners.aEvts.push([fListener]); this["on" + sEventType] = runListeners; > else var aElListeners = oEvtListeners.aEvts[nElIdx]; if (this["on" + sEventType] !== runListeners) aElListeners.splice(0); this["on" + sEventType] = runListeners; > for (var iLstId = 0; iLstId aElListeners.length; iLstId++) if (aElListeners[iLstId] === fListener) return; > > aElListeners.push(fListener); > > else oListeners[sEventType] = aEls: [this], aEvts: [[fListener]] >; this["on" + sEventType] = runListeners; > >; Element.prototype.removeEventListener = function ( sEventType, fListener /*, useCapture (will be ignored!) */, ) if (!oListeners.hasOwnProperty(sEventType)) return; > var oEvtListeners = oListeners[sEventType]; for ( var nElIdx = -1, iElId = 0; iElId oEvtListeners.aEls.length; iElId++ ) if (oEvtListeners.aEls[iElId] === this) nElIdx = iElId; break; > > if (nElIdx === -1) return; > for ( var iLstId = 0, aElListeners = oEvtListeners.aEvts[nElIdx]; iLstId aElListeners.length; iLstId++ ) if (aElListeners[iLstId] === fListener) aElListeners.splice(iLstId, 1); > > >; >
Смотрите также
- EventTarget.addEventListener() .
- Non-standard EventTarget.detachEvent() (en-US).
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 4 авг. 2023 г. by MDN contributors.
Как можно удалить обработчик события, если в качестве аргумента addEventListener передается функция с аргументами?
Добрый день! У меня такая проблема, мне необходимо передать аргумент в обработчик события. Но затем при другом событии нужно нужно этот обработчик удалить. Не могу понять, как это сделать. Пример:
const but1 = useRef(null) const but2 = useRef(null) const handleButtonMove = () => ( (event) => < console.log(event.target) >) const handleButtonClick = (elBut1) => ( (event) => < elBut1.removeEventListener("mousemove", handleButtonMove()) >) useEffect(() => < const elBut1 = but1.current const elBut2 = but2.current elBut1.addEventListener("mousemove", handleButtonMove()) elBut2.addEventListener("click", handleButtonClick(elBut1)) >, []) return ( )
- Вопрос задан более года назад
- 517 просмотров
4 комментария
Простой 4 комментария
зачем вам такая зубодробительная логика с отключением событий? почему нельзя просто блокировать выполнение кода внутри обработчика?
Может код не весь, но вы отписываетесь от событий на которые повесились в useEffect?
andrey_chirkin @andrey_chirkin Автор вопроса
insighter, У меня это встречается в следующей задаче. Есть таблица, в которой размер столбцов должен менять динамически, когда растягиваем столбец. Используется три события мыши: mousedown, mousemove(когда мы тянем столбец, при зажатой мыши), mouseUp. При mouseUp мне нужно удалить событие mouseMove.
const onMouseUpRightResize = (id) => ( () => < document.removeEventListener("mousemove", onMouseMoveRightResize(id)) >) const onMouseMoveRightResize = (id) => ( (event) => < const dx = event.clientX - x x = event.clientX width = width + dx setColWidth() console.log('width =', width) document.addEventListener("mouseup", onMouseUpRightResize(id)) > ) const onMouseDownRightResize = (event) => < x = event.clientX const = event.target console.log('Default width =', width) document.addEventListener("mousemove", onMouseMoveRightResize(id)) >
Как удалить обработчик событий js
Для удаления обработчика событий используется метод removeEventListener() . Первым параметром передаётся тип события, а вторым функция-обработчик:
const div = document.getElementById('div'); const listener = (event) => // обработчик события >; div.addEventListener('click', listener); // добавляем обработчик div.removeEventListener('click', listener); // удаляем обработчик