.addEventListener() — JavaScript — Дока

Кратко

Скопировано

Добавляет элементу действие, которое будет выполнено после срабатывания события. Например, на клик мышки или нажатие клавиши.

Пример

Скопировано

Найдём первую кнопку на странице и будем выводить сообщение в консоль, когда произошёл клик по этой кнопке.

const element = document.querySelector('button')element.addEventListener('click', function (event) {  console.log('Произошло событие', event.type)})
          const element = document.querySelector('button')
element.addEventListener('click', function (event) {
  console.log('Произошло событие', event.type)
})

Как понять

Скопировано

При вызове функции, в неё передаётся специальный объект (в примере выше — event), который у разных типов событий разный. Например, у событий нажатия клавиши есть код клавиши, а у событий перемещения мыши — координаты.

Функция может быть объявлена ранее:

const element = document.querySelector('button')function handleClickFunction(event) {  alert('Именованная функция')}element.addEventListener('click', handleClickFunction)
          
const element = document.querySelector('button') function handleClickFunction(event) { alert('Именованная функция') } element.addEventListener('click', handleClickFunction)

А может быть анонимной:

element.addEventListener('click', function (event) {  alert('Анонимная функция')})
          element.addEventListener('click', function (event) {
  alert('Анонимная функция')
})

🤖 Заранее созданные функции обычно используют, когда функция содержит в себе много кода или к ней нужно ссылаться несколько раз. Например, когда нужно отписаться от события позже. Для отписки используется метод элемента Element.removeEvent

Listener().

Анонимные функции удобно использовать при быстрой разработке или когда обработчик создаётся в одном единственном месте и выносить его в отдельную именованную функцию — дольше, чем писать код самой этой функции. В этом случае очень часто используют короткую, стрелочную запись функции:

element.addEventListener('click', (event) => {  alert('Анонимная функция')})
          element.addEventListener('click', (event) => {
  alert('Анонимная функция')
})

Как пишется

Скопировано

Сигнатура функции выглядит следующим образом

element.addEventListener(eventType, handler, options)
          element.addEventListener(eventType, handler, options)
  • element — любой HTMLElement на странице.
  • eventType — строка, содержащая название события. Наиболее популярные события 'click', 'change', 'submit', 'keydown', 'keyup', 'mousemove', 'mouseenter', 'mouseleave'.
  • handler — функция, которая будет вызвана, когда событие произойдёт.
  • options/capture — необязательный параметр, который описывает дополнительные свойства для срабатывания события.
    • capture — включает или выключает захват события элементом, на который установлен обработчик. Это значит, что событие сначала сработает на элементе и только потом сработает на всех вложенных элементах. Принимает значение true или false
    • options: { capture: bool, passive: bool
      , once: bool }
      — при передаче объекта аргумент будет распознан как объект настроек, так можно установить больше параметров.
      • passive – говорит о том, что внутри handler никогда не будет вызвана функция event.preventDefault(), если функция event.preventDefault() все-таки вызвана, браузер должен её игнорировать и выводить предупредительное сообщение в консоль.
      • once – включает автоматическую отписку от события после первого срабатывания.

Ниже приведено несколько вариантов вызова функции с разными параметрами:

function handleMouseClick(event) {  console.log('Вы нажали на элемент:', event.target)}window.addEventListener('click', handleMouseClick)window.addEventListener('click', handleMouseClick, true)window.addEventListener('click', handleMouseClick, false)window.addEventListener('click', handleMouseClick, {  passive: true,  capture: false,})
          function handleMouseClick(event) {
  console.log('Вы нажали на элемент:', event.target)
}
window.addEventListener('click', handleMouseClick)
window.addEventListener('click', handleMouseClick, true)
window.addEventListener('click', handleMouseClick, false)
window.addEventListener('click', handleMouseClick, {
  passive: true,
  capture: false,
})

У объекта event есть специальные методы, такие как preventDefault() и stopPropagation(). Остальные методы практически не используются:

  • preventDefault() позволяет заблокировать стандартное поведение браузера. Например, по клику на ссылке — заблокировать переход по этой ссылке;
  • stopPropagation() позволяет остановить всплытие события по DOM-дереву.

На практике

Скопировано

Павел Минеев советует

Скопировано

🛠 Обработка передачи третьего параметра для устаревших браузеров:

Проверим, поддерживает ли браузер объект options. Добавим обработчик события на window передав ему объект options, в котором поле passive при попытке доступа к нему будет менять ранее установленную переменную на true. Это значит если браузер будет проверять содержимое

options. passive, значит он поддерживает данные настройки.

let hasPassiveSupport = falsetry {  const options = Object.defineProperty({}, 'passive', {    get() {      hasPassiveSupport = true    },  })  window.addEventListener('test', null, options)} catch (err) {}
          let hasPassiveSupport = false
try {
  const options = Object.defineProperty({}, 'passive', {
    get() {
      hasPassiveSupport = true
    },
  })
  window.addEventListener('test', null, options)
} catch (err) {}

Далее мы можем просто проверить если passive поддерживается то передавать

options иначе передавать false

window.addEventListener(  'resize',  function () {    // обработка события  },  hasPassiveSupport ? { passive: true } : false)
          window.addEventListener(
  'resize',
  function () {
    // обработка события
  },
  hasPassiveSupport ? { passive: true } : false
)

Также, в случае, если вы хотите использовать passive и capture одновременно, то такую проверку можно не делать.
В этом случае старый браузер воспримет переданный объект как true и включит

capture, а новый обработает оба параметра внутри объекта.

window.addEventListener('resize', function () {  // обработка события}, { passive: true, capture: true })
          window.addEventListener('resize', function () {
  // обработка события
}, { passive: true, capture: true })

Дока Дог советует

Скопировано

🛠 Базовая обработка событий клавиатуры.

С помощью событий, можно обрабатывать нажатие клавиш на клавиатуре, когда фокус установлен в поле ввода.
В момент нажатия клавиш будем выводить код клавиши, а по нажатию клавиши Enter добавлять сообщение, которое было введено в поле.

<div>Ожидание ввода...</div><input type="text" placeholder="Введите сообщение"><div></div>
          
<div>Ожидание ввода...</div> <input type="text" placeholder="Введите сообщение"> <div></div>

Для этого подпишемся на событие keydown. Каждое нажатие клавиши будет создавать событие ‘keydown’ и функция будет срабатывать. Внутри функции будем получать код клавиши из свойства key объекта события. Если код клавиши оказался 'Enter', то будем сбрасывать значение в поле ввода и выводить результат.

const element = document.querySelector('input')element.addEventListener('keydown', function (event) { const message = '<code>' + event.key + '</code>' const value = event.target.value if (event.key === 'Enter' && value.length > 0) { const messageElement = document.createElement('div') messageElement.classList.add('message') messageElement.innerText = value document.querySelector('.result').appendChild(messageElement) event.target.value = '' } document.querySelector('.event').innerHTML = message}) const element = document.querySelector('input') element.addEventListener('keydown', function (event) { const message = '<code>' + event. key + '</code>' const value = event.target.value if (event.key === 'Enter' && value.length > 0) { const messageElement = document.createElement('div') messageElement.classList.add('message') messageElement.innerText = value document.querySelector('.result').appendChild(messageElement) event.target.value = '' } document.querySelector('.event').innerHTML = message })
Открыть демо в новой вкладке

🛠 Предотвращение срабатывания события по умолчанию.

В этом примере мы заменим стандартное поведение в случае, когда пользователь кликает на ссылку. Чтобы стандартное поведение не сработало, нужно вызывать метод preventDefault у события.

<a href="https://yandex.ru" target="_blank">Ссылка на Яндекс</a><a href="https://yandex.ru" target="_blank">Ссылка с измененным поведением</a><div></div>
          <a href="https://yandex.ru" target="_blank">Ссылка на Яндекс</a>
<a href="https://yandex. ru" target="_blank">Ссылка с измененным поведением</a>
<div></div>

Подпишемся на событие клика по ссылке и вызовем метод preventDefault. После этого определим собственное поведение элемента. Например, будем выводить сообщение на экран:

const linkElement = document.querySelector('#custom')const resultElement = document.querySelector('#result')linkElement.addEventListener('click', function (event) {  event.preventDefault()  resultElement.innerText = 'Вы нажали на ссылку, но ничего не произошло!'  setTimeout(function () {    resultElement.innerText = ''  }, 2500)})
          const linkElement = document.querySelector('#custom')
const resultElement = document.querySelector('#result')
linkElement.addEventListener('click', function (event) {
  event.preventDefault()
  resultElement.innerText = 'Вы нажали на ссылку, но ничего не произошло!'
  setTimeout(function () {
    resultElement.innerText = ''
  }, 2500)
})
Открыть демо в новой вкладке

javascript — Как просмотреть событие, назначенное с помощью addEventListener

Вопрос задан

Изменён 8 месяцев назад

Просмотрен 232 раза

Я хотел бы просмотреть событие, зарегистрированное с помощью element. addEventListener. Как это сделать? Желательно без полифиллов и обёрток. Мне обязателен код обработчика.

  • javascript
  • html
  • html5
  • frontend

2

В devtools, выберите элемент, рядом со вкладкой стили есть вкладка Event Listeners, там вы можете увидеть все слушатели, которые вы добавили на элемент.

Если я правильно понял подоплеку вопроса, речь о том чтобы получить эти сведения через JS а не devtools. Плохая новость в том что это не возможно.

document.querySelector('#test2')
  .addEventListener('click', () => {
      console.log('test2')
}, false)
document.querySelector('#output1').innerText = document.querySelector('#test1').onclick
document.querySelector('#output2').innerText = document.querySelector('#test2').click
<button>test1</button>
<pre></pre>
<button>test2</button>
<pre></pre>

Есть конечно обходной вариант — сделать обертку над addEventListener на все элементы например через querySelectorAll('*') до того как отработают другие скрипты, это может подойти для тестирования своего кода, но вряд ли подойдет в других случаях. А иным способом сделать это не возможно, так как там нативный код.

// сохраняем оригинальную функцию 
const old = document.querySelector('#test3').addEventListener
document.querySelector('#test3').addEventListener = function(){
  console.log(arguments[1])
  old.apply(this, arguments) // вызываем оригинальную функцию
}
document.querySelector('#test3')
  .addEventListener('click', () => {
      console.log('test3')
}, false)
document.querySelector('#output3').innerText = document.querySelector('#test3').click
<button>test3</button>
<pre></pre>

И третий самый героический путь, смотреть исходники devtools как это там реализованно и писать свое расширение которое будет взаимодействовать со страницей или еще как-то выводить информацию о событиях.

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки

Ссылка на событие | MDN

Тип события Описание Документация
Анимация

События, связанные с API веб-анимации.

Используется для реагирования на изменения состояния анимации (например, когда анимация начинается или заканчивается).

Анимационные события запущены Документ , Окно , HTMLЭлемент .
Асинхронная выборка данных

События, связанные с получением данных.

События запущены сигнал прерывания , XMLHttpRequest , FileReader .
Буфер обмена

События, связанные с API буфера обмена.

Используется для уведомления об вырезании, копировании или вставке содержимого.

События запущены Документ , Элемент , Окно .
Состав

События, связанные с композицией; ввод текста «косвенно» (а не с помощью обычных нажатий клавиатуры).

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

События запущены Элемент .
Переход CSS

События, связанные с CSS-переходы.

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

События запущены Документ , HTMLЭлемент , Окно .
База данных

События, связанные с операциями с базой данных: открытие, закрытие, транзакции, ошибки и т. д.

События запущены IDBDatabase , IDBOpenDBRequest , IDBRequest , IDBTransaction .
Мутация DOM

События, связанные с изменениями объектной модели документа (DOM) иерархия и узлы.

Предупреждение: Мутационные события устарел. Наблюдатели за мутациями вместо этого следует использовать.

Перетаскивание, колесо

События, связанные с использованием API перетаскивания HTML и колесные события.

События перетаскивания и колеса являются производными от событий мыши. Пока они запускаются при использовании колесика мыши или перетаскивании, их также можно использовать с другое подходящее оборудование.

События перетаскивания запущены Документ

События Wheel запущены Документ и Элемент

Фокус

События, связанные с получением и потерей фокуса элементами.

События запущены Элемент , Окно .
Форма

События, связанные с созданием, сбросом и отправкой форм.

События запущены HTMLFormElement .
Полноэкранный режим

События, связанные с Полноэкранный API.

Используется для уведомления при переходе между полноэкранным и оконным режимами. режимов, а также ошибок, возникающих при этом переходе.

События запущены Документ , Элемент .
Геймпад

События, связанные с API геймпада.

События запущены Окно .
Жесты

Сенсорные события рекомендуется для реализации жестов.

События запущены Документ , Элемент .

Кроме того, есть ряд нестандартных жестовых событий:

  • Нестандартные специфические события WebKit на Элемент : жестстарт событие, событие смены жеста , жестконец события.
История

События, связанные с API истории.

События запущены Окно .
Управление отображением содержимого элементов HTML

События, связанные с изменением состояния отображения или текстового элемента.

События запущены HTMLDetailsElement , HTMLDialogElement , HTMLSlotElement .
Входы

События, связанные с элементами ввода HTML, например. <ввод> , <выбор> или <текстовое поле> .

События запущены HTMLЭлемент , HTMLInputElement .
Клавиатура

События, связанные с использованием клавиатура.

Используется для уведомления о перемещении клавиш вверх, вниз или простом нажатии.

События запущены Документ , Элемент .
Загрузка/выгрузка документов

События, связанные с загрузкой и выгрузкой документов.

События запущены Документ и Окно .

Манифесты

События, связанные с установкой прогрессивные манифесты веб-приложений.

События запущены Окно .
Медиа

События, связанные с использованием СМИ (включая API захвата мультимедиа и потоков, API веб-аудио, API «картинка в картинке» и т. д.).

События запущены ScriptProcessorNode , HTMLMediaElement , Аудиотреклист , AudioScheduledSourceNode , МедиаРекордер , Медиапоток , Медиастримтрек , Видеотреклист , HTMLTrackElement , OfflineAudioContext , ТекстТрек , Тексттреклист , Элемент/аудио, Элемент/видео.
Обмен сообщениями

События, связанные с получением окном сообщения от другого браузера контекст.

События запущены Окно .
Мышь

События, связанные с использованием компьютерная мышь.

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

События указателя обеспечивают аппаратно-независимую альтернативу мыши. события. События перетаскивания и колеса являются производными от событий мыши.

События мыши запущены Элемент
Сеть/соединение

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

События запущены Окно .

События запущены Информация о сети (API сетевой информации).

Платежи

События, связанные с API запроса платежа.

События запущены Запрос Платежа , Ответ на платеж .

Производительность

События, связанные с API времени с высоким разрешением, API временной шкалы производительности, API синхронизации навигации, API синхронизации пользователей, и API синхронизации ресурсов.

События запущены Производительность .

Указатель

События, связанные с API событий указателя.

Предоставляет аппаратно-независимые уведомления от указывающих устройств включая мышь, сенсорный экран, ручку/стилус.

События запущены Документ , HTMLЭлемент .
Печать

События, связанные с печатью.

События запущены Окно .
Отклонение обещания

События, отправленные в глобальный контекст скрипта, когда любое обещание JavaScript отвергается.

События запущены Окно .
Розетки

События, связанные с API веб-сокетов.

События запущены Веб-сокет .
СВГ

События, связанные с изображениями SVG.

События запущены СВГЭлемент , SVGAnimationElement , SVGGraphicsElement .

Выбор текста

События API выбора связанные с выделением текста.

Событие ( selectionchange ) запущено HTMLTextAreaElement , HTMLInputElement .

Сенсорный

События, связанные с Коснитесь API событий.

Предоставляет уведомления о событиях взаимодействия с сенсорным экраном. экрана (т. е. с помощью пальца или стилуса). Не связанный с API принудительного касания.

События запущены Документ , Элемент .
Виртуальная реальность

События, связанные с API устройства WebXR.

Предупреждение: WebVR API (и связанный События окна ) устарели.

События запущены XRСистема , сессия XRS , XRReferenceSpace .
RTC (связь в реальном времени)

События, связанные с WebRTC-API.

События запущены RTCDataChannel , RTCDTMFSender , РТЦИсТранспорт , RTCPeerConnection .
События, отправленные сервером

События, связанные с API событий, отправленных сервером.

События запущены Источник событий .
Речь

События, связанные с API веб-речи.

События запущены Синтез РечиВысказывание .
Рабочие

События, связанные с API веб-воркеров, API сервисного работника, API широковещательного канала и API обмена сообщениями канала.

Используется для ответа на новые сообщения и ошибки отправки сообщений. Услуга работники также могут быть уведомлены о других событиях, включая push-уведомления. уведомления, пользователи нажимают на отображаемые уведомления, которые нажимают подписка аннулирована, удаление элементов из контента индекс и т.д.

События запущены Сервисворкерглобалскопе , Дедикатедворкерглобалскопе , SharedWorkerGlobalScope , WorkerGlobalScope , Worker , WorkerGlobalScope , Широковещательный канал , Порт сообщений .

Подробное руководство по прослушивателям событий JavaScript

Независимо от того, являетесь ли вы новичком в JavaScript или занимаетесь программированием десятилетиями, вам придется использовать прослушиватели событий практически в любом проекте, который вы создаете. Эти обработчики событий на первый взгляд кажутся простыми, но есть множество менее известных функций обработчиков событий, таких как всплытие, захват, делегирование и многое другое. Понимание этих функций имеет решающее значение для того, чтобы стать опытным разработчиком JavaScript, поэтому независимо от того, где вы находитесь в своем путешествии по программированию, в этой статье будет что-то для вас.

Если вы предпочитаете учиться визуально, посмотрите видеоверсию этой статьи.

Основы прослушивателя событий

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

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

Чтобы настроить прослушиватель событий, вам просто нужно иметь переменную, которая ссылается на элемент, а затем вызвать функцию addEventListener для этого элемента. Эта функция принимает как минимум два параметра.

Первый параметр — это просто строка, представляющая собой имя события для прослушивания. Существуют сотни событий, которые вы можете прослушивать, например click , input и mousemove . Это полный список событий, но на самом деле вы будете использовать только некоторые из этих событий, так что не утруждайте себя запоминанием их всех.

Второй параметр — это функция, которая имеет один единственный аргумент — аргумент события, обычно называемый e . Эта функция вызывается каждый раз, когда происходит событие, и объект события содержит информацию о событии. В зависимости от того, какое событие вы прослушиваете, объект события будет иметь разные важные свойства, но почти каждое событие будет иметь свойство target . Это свойство представляет элемент, в котором происходит событие, что важно для более продвинутого использования прослушивателей событий, которые мы рассмотрим позже в этой статье.

Также важно отметить, что если у вас есть несколько обработчиков событий в элементе для одного и того же события, все они будут срабатывать в том порядке, в котором они были добавлены к элементу.

Распространение событий

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

Представьте, что у нас есть следующие HTML и JavaScript.

Если мы щелкнем внутри дочернего элемента, вы, вероятно, подумаете, что он зарегистрирует Дочерний элемент , но на самом деле он зарегистрирует как Дочерний элемент , так и Родительский элемент в указанном порядке. Причиной этого является пузырение.

Этап всплывающей подсказки

Когда событие запускается для элемента, это событие всплывает вверх по дереву документа ко всем элементам, внутри которых находится этот элемент. В нашем примере, когда дочерний элемент щелкнут, он также вызовет прослушиватель события щелчка на родительском элементе, поскольку дочерний элемент находится внутри родительского элемента. Это даже делает еще один шаг вперед и запускает прослушиватель событий щелчка в самом документе. Мы воспользуемся этим фактом, когда будем иметь дело с делегированием событий.

Фаза захвата

Теперь все, что я объяснил выше, имеет отношение к фазе пузырька, которая является фазой по умолчанию, когда срабатывают прослушиватели событий, но у событий также есть еще одна фаза, называемая фазой захвата, которая происходит первой. Фаза захвата аналогична фазе пузырька, но событие начинается с элемента верхнего уровня, в нашем случае с документа, и продвигается внутрь. Это означает, что в нашем примере, если мы нажмем на дочерний элемент, мы вызовем прослушиватель событий захвата для документа, затем для родителя, затем для дочернего элемента. Затем мы войдем в фазу пузырьков и запустим прослушиватели событий пузырьков для дочернего элемента, затем для родителя, а затем для документа.

До сих пор мы рассмотрели только то, как настроить прослушиватели событий для фазы всплывающих окон, но если вы хотите иметь прослушиватель событий захвата, вам нужно использовать третий параметр функции addEventListener . Этот третий параметр представляет собой объект параметров, который имеет свойство захвата , которое, если установлено значение true, будет помечать это событие как событие захвата.

С приведенным выше кодом, если мы нажмем на ребенка, он выйдет из системы следующим образом.

Как вы можете видеть, все прослушиватели событий захвата, которые мы создали, срабатывают первыми, а затем срабатывают прослушиватели событий пузырьков.

Остановка распространения событий

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

Используя метод stopPropagation для объекта события, мы можем остановить продолжение захвата и всплытия события, что означает, что если в цепочке есть какие-либо другие прослушиватели событий, которые будут срабатывать, они этого не сделают. В приведенном выше примере только Родительский захват будет зарегистрирован, так как мы остановим распространение события после прослушивателя родительского события захвата.

Другой метод, stopImmediatePropagation , доступен для объекта события, и он работает немного иначе. Если вы используете stopImmediatePropagation , то событие не только остановит распространение к дочерним/родительским элементам через фазы пузырька и захвата, но также остановит запуск других событий в элементе.

В приведенном выше примере мы остановили распространение в первом родительском прослушивателе событий захвата, что предотвращает распространение события на другие элементы через фазы захвата/пузырька. Кроме того, поскольку мы использовали stopImmediatePropagation , все остальные прослушиватели событий щелчка на родительском элементе также не будут срабатывать. Важно отметить, что прослушиватели событий для одного и того же элемента будут запускаться в том порядке, в котором они определены, поэтому, если вы хотите, чтобы другие прослушиватели событий не срабатывали с помощью этого метода, они должны быть определены после прослушивателя, который останавливает распространение.

Важные примечания о всплывающей подсказке

Одна важная вещь, которую следует знать о всплывающей подсказке событий, заключается в том, что всплывают не все события. Такие события, как событие focus , которое срабатывает, когда элемент получает фокус, не всплывают. Как правило, события, которые не всплывают, имеют смысл не всплывать, поскольку они относятся только к отдельному элементу, для которого срабатывает событие, например, к событию focus .

Удаление прослушивателей событий

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

removeEventListener

Функция removeEventListener — это простая функция, которую можно вызвать для элемента, чтобы удалить прослушиватель событий, который был ранее добавлен с помощью addEventListener .

Приведенный выше код добавляет прослушиватель по щелчку, который вызывает функцию sayHi , а затем немедленно удаляет ее. Важно отметить, что при добавлении/удалении прослушивателей событий вам необходимо убедиться, что функция точно такая же. Если бы вместо этого я написал свой код следующим образом, он фактически не удалил бы прослушиватель событий, поскольку это две разные функции, даже если они содержат один и тот же код.

Если вы не знаете, почему это так, вам следует ознакомиться с моим полным справочником по сравнению со значениями, в котором объясняется именно эта концепция.

Запуск событий один раз

Общепринятой практикой является запуск события только один раз, и делать это с помощью removeEventListener немного неудобно и не всегда точно. Вот почему третий параметр options для addEventListener имеет свойство с именем Once , которое, если установлено значение true, гарантирует, что ваш прослушиватель событий запускается только один раз.

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

Прерываемые прослушиватели событий

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

Приведенный выше код выглядит немного запутанным, но я попытаюсь объяснить, что происходит. Сначала мы создаем новый AbortController . Затем мы берем этот AbortController и передаем его свойство signal в свойство signal объекта options для нашей функции addEventListener . Это соединяет наш прослушиватель событий с этим AbortController , поэтому, если мы прервем его, он удалит прослушиватель событий. Затем, наконец, в нашем коде мы вызываем метод прерывания на нашем AbortController , когда счетчик больше или равен 3, который удалит прослушиватель событий.

По сути, способ работы AbortController заключается в том, что вы передаете часть сигнала функции addEventListener , а затем в любое время в будущем вы можете вызвать abort на AbortController , и он удалит прослушиватель событий для вас. .

Делегирование событий

Все концепции, которые мы рассмотрели до сих пор, привели к последней теме этой статьи, которая касается делегирования событий. На мой взгляд, понимание того, как это работает, является наиболее важной концепцией в этой статье.

В приведенном выше коде мы выбираем все кнопки на нашей странице и добавляем прослушиватель событий для прослушивания нажатия на эти кнопки. Затем после всего этого мы добавляем новую кнопку на страницу. К этой новой кнопке НЕ подключен какой-либо прослушиватель событий щелчка, поскольку он был добавлен на страницу после добавления наших прослушивателей событий.

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

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

Поскольку событие щелчка поднимается вверх к родительским элементам, мы знаем, что в конечном итоге любое событие щелчка на нашей странице попадет в документ. Затем мы проверяем документ, чтобы увидеть, соответствует ли цель события кнопке селектора 9.0023 . Этот селектор, который мы передаем в , соответствует , — это просто селектор CSS, аналогичный тому, который вы передаете в querySelector .

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