Событие DOM - это программный интерфейс, предназначенный для уведомления кода о каких-либо изменениях в окне браузера; это сигнал от браузера о том, что что-то произошло с каким-либо DOM-узлом.
События (в общем случае) могут возникать в результате действий пользователя (например, использование мыши или изменение размера окна), изменения состояния базовой среды (например, низкий заряд батареи или мультимедийные события из операционной системы) и других причин.
Объект события - это объект, который создается браузером, основанный на интерфейсе Event, и в который записываются данные, описывающие это событие и предназначенные для их передачи в качестве аргументов функции-обработчика. Т.о. объект события может иметь дополнительные поля и (или) функции, позволяющие получить дополнительную информацию о том, что произошло (от простых действий пользователя до действий автоматизированной системы рассылки уведомлений, создаваемых моделью формирования экрана).
Список различных типов событий на MDN https://developer.mozilla.org/ru/docs/Web/Events.
Виды событий DOM:
- События ресурса (запускаются для ресурса (или объекта Element), когда ресурс не может быть загружен или не может быть использован).
- Сетевые события (браузер получил или потерял доступ к сети).
- События фокуса (Element получил или потерял фокус).
- События соединения с WebSocket.
- События журнала сессии.
- События CSS-анимации (CSS-анимация началась, прервалась, завершена, повторяется; подробнее о transitions https://developer.mozilla.org/ru/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions).
- События формы (кнопка "Сброс" нажата, кнопка "Отправить" нажата).
- События печати (диалоговое окно печати открыто или закрыто).
- События Text Composition (происходит, когда подготавливается композиция отрывка текста: аналогично нажатию клавиш для ввода с клавиатуры, но работает с другими входами, такими как распознавание речи).
- События представления элемента (Element был переведён в полноэкранный режим или обратно, изменён размер просмотра документа, документ или элемент были прокручены).
- События буфера обмена (выделенное было вырезано и (или) скопировано в буфер обмена, содержимое буфера обмена было вставлено).
- События клавиатуры (нажатие или отпускание клавиш).
- События "мыши".
- События перетаскивания (Drag & Drop).
- События медиа-содержимого.
- События выполнения (Progress-события).
- События хранилища
- События обновления
- События изменения значений
- Другие (в т.ч. нестандартные) события.
Обработчики событий
Обработчик события - это функция, которая срабатывает в момент события, что позволяет приложению реагировать на действия пользователя.
Способы назначения обработчика события:
- используя атрибут элемента HTML:
- указывая код обработчика внутри HTML-кода элемента (например, <input type="button" value="Нажми меня" onclick="alert('Нажатие!')">);
- с выносом кода обработчика в отдельную JavaScript-функцию и её вызовом внутри HTML-кода элемента (например, <input type="button" value="Нажми меня" onclick="clckButton()">, где clckButton() - функция-обработчик);
- используя свойства DOM-объекта (например, element.onclick = fn(){} или element.onclick = fn);
- используя специальные методы addEventListener() и removeEventListener().
Особенности назначения обработчиков событий:
- Обработчики всегда хранятся в свойствах DOM-объекта, а атрибуты HTML – лишь один из способов их инициализации. Так как имена свойств элемента DOM должны быть уникальными, то назначить несколько обработчиков с одинаковыми именами нельзя (повторная инициализация перезапишет код обработчика).
- Не используйте setAttribute() для обработчиков (setAttribute('onclick', function() { }) работать не будет).
- Регистр DOM-свойства имеет значение (используйте elem.onclick, а не elem.ONCLICK).
Невозможность повесить несколько обработчиков на одно событие - недостаток первых двух способов (addEventListener() этого недостатка лишен).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<div> <input class="btn" type="button" value="Нажми меня" onclick="document.querySelector('.myText').value='Первая инициализация'"></input> <input class="myText" type="text"></input> </div> <script> let elBtn = document.querySelector(".btn"); let elTxt = document.querySelector(".myText"); // перезапишет обработчик onclick, размещенный в HTML-коде elBtn.onclick = function () { elTxt.value = "Нажатие!"; }; </script> |
Убрать обработчик можно передачей в его значение null (например, elem.onclick = null).
С выносом кода обработчика в отдельную JavaScript-функцию и её вызовом внутри HTML-кода элемента:
1 2 3 4 5 6 7 8 |
<div> <input type="button" value="Нажми меня" onclick="clckButton()"> <input class="myText" type="text"></input> </div> <script> function clckButton() { (document.querySelector(".myText").value = "Нажатие!") } </script>; |
С использованием свойств DOM-объекта:
1 2 3 4 5 6 7 8 9 10 11 12 |
<div> <input class="btn" type="button" value="Нажми меня"> <input class="myText" type="text"></input> </div> <script> let elBtn = document.querySelector(".btn"); // получаем элемент по селектору class let elTxt = document.querySelector(".myText"); // получаем элемент по селектору class elBtn.onclick = function () { // назначаем обработчик события onclick elTxt.value = "Нажатие!"; }; </script> |
Или так:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<div> <input class="btn" type="button" value="Нажми меня"> <input class="myText" type="text"></input> </div> <script> let elBtn = document.querySelector(".btn"); // получаем элемент по селектору class let elTxt = document.querySelector(".myText"); // получаем элемент по селектору class elBtn.onclick = click; // назначаем обработчик события onclick (без вызова, вызывающие скобки не нужны) function click() { elTxt.value = "Нажатие!"; } </script> |
This внутри обработчика события
Внутри обработчика события this ссылается на тот элемент (event.currentTarget), которому назначен обработчик, например:
1 2 3 4 5 6 7 8 9 10 |
<div id="myDiv"> <input id="btn" type="button" value="Кнопка"></input> </div> <script> let el = document.querySelector("#btn"); el.onclick = function modifyText(eventModify) { el.value = this.nodeName; // INPUT }; </script> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<button id="btn-msg" data-text='Custom message'>Show message</button> <script> "use strict" let btnMsg = document.getElementById("btn-msg") btnMsg.addEventListener("click", (event) => alert(event.target.dataset.text)) // или btnMsg.addEventListener("click", function (event) { alert(this.dataset.text) }) // а так работать не будет: btnMsg.addEventListener("click", (event) => alert(this.dataset.text)) // стрелочная функция, this => глобальный объект window </script> |
Метод addEventListener()
Метод EventTarget.addEventListener() регистрирует определённый обработчик события, вызванного на EventTarget.
EventTarget может быть Element, Document, Window, или любым другим объектом, поддерживающим события (таким как XMLHttpRequest).
Синтаксис:
1 2 3 |
target.addEventListener(type, listener[, options]); target.addEventListener(type, listener[, useCapture]); target.addEventListener(type, listener[, useCapture, wantsUntrusted ]); // только Gecko/Mozilla |
где
- type - чувствительная к регистру строка, представляющая тип обрабатываемого события;
- listener - объект, принимающий уведомление, когда событие указанного типа произошло (это может быть объект, реализующий интерфейс EventListener или просто функция JavaScript);
- options (необязательный) - объект, который определяет характеристики объекта, прослушивающего событие:
- capture: Boolean - указывает, что события этого типа будут отправлены зарегистрированному обработчику listener перед отправкой на EventTarget, расположенный ниже в дереве DOM (фаза, на которой должен сработать обработчик, подробнее Всплытие и погружение (перехват) событий DOM);
- once: Boolean - указывает, что обработчик должен быть вызван не более одного раза после добавления (если true, то обработчик автоматически удаляется при вызове);
- passive: Boolean - указывает, что обработчик никогда не вызовет preventDefault(). Если всё же вызов будет произведён, браузер должен игнорировать его и генерировать консольное предупреждение;
- mozSystemGroup: Boolean - указывает, что обработчик должен быть добавлен в системную группу (доступно только в коде, запущенном в XBL или в расширении Chrome);
- wantsUntrusted - если true, то обработчик будет получать сгенерированные события, посланные со страницы (по умолчанию равно false для Сhrome и true для обычных веб-страниц). Этот параметр доступен только в Gecko и в основном полезен для использования в дополнениях и самом браузере. Смотрите Взаимодействие между привилегированными и непривилегированными страницами для примеров использования.
Прежде чем использовать определённое значение в объекте options, рекомендуется убедиться, что браузер пользователя поддерживает его, поскольку это дополнение, которое не все браузеры поддерживали исторически.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<table id="outside"> <tr> <td id="t1">один</td> </tr> <tr> <td id="t2">два</td> </tr> </table> <script> // Добавляем обработчик событий для таблицы let el = document.getElementById("outside"); // выбрали элемент по id el.addEventListener("click", modifyText, false); // назначили обработчик // Функция изменяет содержимое t2 function modifyText() { let t2 = document.getElementById("t2"); t2.textContent == "три" ? (t2.textContent = "два") : (t2.textContent = "три"); } </script> |
Достоинства метода addEventListener():
- позволяет добавлять множество обработчиков для одного события;
- предоставляет точный контроль фазы срабатывания (вызова) обработчика (погружение или всплытие);
- срабатывает на любом DOM-элементе, а не только на HTML-элементах.
Метода, который позволяет получить из элемента обработчики событий, назначенные через addEventListener(), не существует.
Для удаления обработчиков событий, назначенных через addEventListener(), используется метод removeEventListener(). При этом в него нужно передать именно ту функцию-обработчик, которая была назначена с помощью addEventListener(), например:
1 2 |
el.addEventListener("click", modifyText, false); // назначили обработчик el.removeEventListener("click", modifyText, false); // удалили обработчик |
Т.о., если функцию-обработчик не сохранить, то удалить её не получится.