Кратко
СкопированоДобавляет элементу действие, которое будет выполнено после срабатывания события. Например, на клик мышки или нажатие клавиши.
Пример
СкопированоНайдём первую кнопку на странице и будем выводить сообщение в консоль, когда произошёл клик по этой кнопке.
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.
Альтернативный способ отписки от события можно реализовать с помощью объекта Abort. Подробнее о нём читайте в разделе «На практике».
Анонимные функции удобно использовать при быстрой разработке или когда обработчик создаётся в одном единственном месте и выносить его в отдельную именованную функцию — дольше, чем писать код самой этой функции. В этом случае очень часто используют короткую, стрелочную запись функции:
element.addEventListener('click', (event) => { alert('Анонимная функция')})
element.addEventListener('click', (event) => {
alert('Анонимная функция')
})
Как пишется
СкопированоСигнатура функции выглядит следующим образом:
element.addEventListener(eventType, handler, options)
element.addEventListener(eventType, handler, options)
element— любой HTMLElement на странице.event— строка, содержащая название события. Наиболее популярные событияType 'click','change','submit','keydown','keyup','mousemove','mouseenter','mouseleave'.handler— функция, которая будет вызвана, когда событие произойдёт.options— необязательный параметр, который описывает дополнительные свойства для срабатывания события./ capture capture— включает или выключает захват события элементом, на который установлен обработчик. Это значит, что событие сначала сработает на элементе и только потом сработает на всех вложенных элементах. Принимает значениеtrueилиfalseoptions— при передаче объекта аргумент будет распознан как объект настроек, так можно установить больше параметров.: { capture : bool , passive : bool , once : bool , signal : Abort Signal } passive— значениеtrueозначает что внутриhandlerникогда не будет вызвана функцияevent, если функция. prevent Default ( ) eventвсё-таки вызвана, браузер должен её игнорировать и выводить предупредительное сообщение в консоль.. prevent Default ( ) once— включает автоматическую отписку от события после первого срабатывания.signal— передаётся ссылка на объект сигналаAbort, который позволяет отписаться от события.Signal
Ниже приведено несколько вариантов вызова функции с разными параметрами:
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})const abortController = new AbortController()window.addEventListener('click', handleMouseClick, { signal: abortController.signal})
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
})
const abortController = new AbortController()
window.addEventListener('click', handleMouseClick, {
signal: abortController.signal
})
У объекта event есть специальные методы, такие как prevent и stop. Остальные методы практически не используются:
preventпозволяет заблокировать стандартное поведение браузера. Например, по клику на ссылке — заблокировать переход по этой ссылке.Default ( ) stopпозволяет остановить распространение события по DOM-дереву.Propagation ( )
На практике
Скопированосоветует
Скопировано🛠 Обработка передачи третьего параметра для устаревших браузеров.
Проверим, поддерживает ли браузер объект options. Добавим обработчик события на window, передав ему объект options. В нём поле passive будет менять ранее установленную переменную на true при попытке доступа к объекту. Если браузер проверит содержимое options, он поддерживает данные настройки.
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 объекта события. Если код клавиши оказался ', то будем сбрасывать значение в поле ввода и выводить результат.
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
})
🛠 Предотвращение срабатывания события по умолчанию.
В этом примере мы заменим стандартное поведение в случае, когда пользователь кликает на ссылку. Чтобы стандартное поведение не сработало, нужно вызывать метод prevent у события.
<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>
Подпишемся на событие клика по ссылке и вызовем метод prevent. После этого определим собственное поведение элемента. Например, будем выводить сообщение на экран:
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)
})
советует
Скопировано🛠 Базовый пример использования Abort для отписки от слушателя событий.
По умолчанию в большинстве случаев для отписки стоит использовать remove. Но, если при подписке была использована анонимная функция, то отписаться от такого слушателя через remove не получится, так как вторым параметром необходимо передать ссылку на функцию-обработчик.
const abortController = new AbortController()const element = document.querySelector('#element1')element.addEventListener('click', () => console.log('Подписка активна'), { signal: abortController.signal})// Вызываем, когда захотим отписаться:abortController.abort()
const abortController = new AbortController()
const element = document.querySelector('#element1')
element.addEventListener('click', () => console.log('Подписка активна'), {
signal: abortController.signal
})
// Вызываем, когда захотим отписаться:
abortController.abort()
🛠 Отписка сразу от нескольких обработчиков.
Abort может быть удобнее, чем remove в случае, если нам нужно отписаться сразу от нескольких обработчиков:
const abortController = new AbortController()const element1 = document.querySelector('#element1')const element2 = document.querySelector('#element2')element1.addEventListener('click', () => { // ...}, {signal: abortController.signal})element2.addEventListener('click', () => { // ...}, {signal: abortController.signal})// Отписываемся одним вызовом сразу от двух обработчиковabortController.abort()
const abortController = new AbortController()
const element1 = document.querySelector('#element1')
const element2 = document.querySelector('#element2')
element1.addEventListener('click', () => {
// ...
}, {signal: abortController.signal})
element2.addEventListener('click', () => {
// ...
}, {signal: abortController.signal})
// Отписываемся одним вызовом сразу от двух обработчиков
abortController.abort()
🛠 Вешаем слушатель событий на Abort.
В случае, если необходимо реализовать логику после отписки, то можно слушать событие abort на Abort:
const abortController = new AbortController()const signal = abortController.signalsignal.addEventListener('abort', () => { console.log('Операция отменена')})
const abortController = new AbortController()
const signal = abortController.signal
signal.addEventListener('abort', () => {
console.log('Операция отменена')
})