.addEventListener()

Учим приложение реагировать на действия пользователя.

Время чтения: меньше 5 мин

Кратко

Скопировано

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

Пример

Скопировано

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

        
          
          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.removeEventListener().

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

        
          
          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 class="event">Ожидание ввода...</div><input type="text" placeholder="Введите сообщение"><div class="result"></div>
          <div class="event">Ожидание ввода...</div>
<input type="text" placeholder="Введите сообщение">
<div class="result"></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" id="custom">Ссылка с измененным поведением</a><div id="result"></div>
          <a href="https://yandex.ru" target="_blank">Ссылка на Яндекс</a>
<a href="https://yandex.ru" target="_blank" id="custom">Ссылка с измененным поведением</a>
<div id="result"></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)
})

        
        
          
        
      
Открыть демо в новой вкладке