Если в коде JavaScript возникает событие, то его обрабатывает связанный с этим событием обработчик. Рассмотрим, как определять обработчики событий.
Самый простой способ определения обработчиков событий - их установка в коде html. Это так называемые встроенные обработчики или inline-обработчики,
которые определяются в коде элемента с помощью атрибутов. Подобные атрибуты начинаются с префикса on. Например, у многих html-элементов есть
атрибут onclick
, который определяет обработчик нажатия элемента. Посмотрим на примере кнопки:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>METANIT.COM</title> </head> <body> <button onclick="console.log('Clicked!')">Click Me</div> </body> </html>
С помощью атрибута onclick="console.log('Clicked!')"
к кнопке прикрепляется обработчик ее нажатия. Этот обработчик состоит из одной инструкции
JavaScript - console.log("Clicked!")
, которая выводит сообщение на консоль. Таким образом, при нажатии на кнопку сработает событие нажатия, и будет
выполняться обработчик из атрибута onclick:
Можно даже определить несколько инструкций подобным образом:
<button onclick="console.log('Hello');console.log('Clicked!')">Click Me</div>
Но, очевидно, что это не самый удобный способ. Но также можно вынести все инструкции в отдельную функцию JavaScript. А атрибуту onclick
передать вызов этой функции:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>METANIT.COM</title> </head> <body> <button onclick="btn_click()">Click Me</div> <script> let clicks = 0; // счетчик нажатий function btn_click(){ console.log("Clicked", ++clicks); } </script> </body> </html>
Теперь по нажатию кнопки будет вызываться функция btn_click, которая определена в коде JavaScript.
Хотя этот подход прекрасно работает, но он имеет кучу недостатков:
Код html смешивается с кодом JavaScript, в связи с чем становится труднее разрабатывать, отлаживать и поддерживать приложение
Обработчики событий можно задать только для уже созданных на веб-странице элементов. Динамически создаваемые элементы в этом случае лишаются возможности обработки событий
К элементу для одного события может быть прикреплен только один обработчик
Нельзя удалить обработчик без изменения кода
Проблемы, которые возникают при использовании встроенных обработчиков, были призваны решить свойства обработчиков. Подобно тому, как у html-элементов есть атрибуты для обработчиков, так и в коде javascript у элементов DOM мы можем получить свойства обработчиков, которые соответствуют атрибутам:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>METANIT.COM</title> </head> <body> <button id="btn">Click Me</div> <script> let clicks = 0; // счетчик нажатий function btn_click(){ console.log("Clicked", ++clicks); } // устанавливаем обработчик нажатия для элемента с id="btn" document.getElementById("btn").onclick = btn_click; </script> </body> </html>
В итоге нам достаточно взять свойство onclick и присвоить ему функцию, используемую в качестве обработчика. За счет этого код html отделяется от кода javascript.
Несмотря на то, что свойства обработчиков решают ряд проблем, которые связаны с использованием атрибутов, в то же время это также не оптимальный подход. Еще один способ установки обработчиков событий представляет использование слушателей.
Для работы со слушателями событий в JavaScript есть объект EventTarget, который определяет методы addEventListener() (для добавления слушателя) и removeEventListener() для удаления слушателя. И поскольку html-элементы DOM тоже являются объектами EventTarget, то они также имеют эти методы. Фактически слушатели представляют те же функции обработчиков.
Метод addEventListener()
принимает два параметра: название события без префикса on и функцию обработчика этого события. Например:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>METANIT.COM</title> </head> <body> <button id="btn">Click Me</div> <script> let clicks = 0; // счетчик нажатий function btn_click(){ console.log("Clicked", ++clicks); } const btn = document.getElementById("btn"); // прикрепляем обработчик события "click" btn.addEventListener("click", btn_click); </script> </body> </html>
То есть в данном случае опять же обрабатывается событие click. Удаление слушателя аналогично добавлению:
rect.removeEventListener("click", btn_click);
Преимуществом использования слушателей является и то, что мы можем установить для одного события несколько функций:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>METANIT.COM</title> </head> <body> <button id="btn">Click Me</div> <script> let clicks = 0; // счетчик нажатий function btn_click(){ console.log("Clicked", ++clicks); } const btn = document.getElementById("btn"); // прикрепляем первый обработчик события "click" в виде функции btn_click btn.addEventListener("click", btn_click); // прикрепляем второй обработчик события "click" в виде анонимной функции btn.addEventListener("click", function(){ console.log("Button clicked!") }); // прикрепляем третий обработчик события "click" в виде стрелочной функции btn.addEventListener("click", ()=>console.log("Element clicked!")); </script> </body> </html>