Как удалить обработчик событий js
Перейти к содержимому

Как удалить обработчик событий js

  • автор:

.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 комментария

insighter

зачем вам такая зубодробительная логика с отключением событий? почему нельзя просто блокировать выполнение кода внутри обработчика?

Может код не весь, но вы отписываетесь от событий на которые повесились в 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); // удаляем обработчик 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *