addEventListener()
Содержание- Синтаксис
- removeEventListener()
- Объект события
- Популярные события
- Как добавить обработчик на множество элементом
- addEventListener и forEach
- Делегирование событий
- Всплытие и погружение
- Получаем доступ к элементу через this
- Итого
Метод addEventListener - это самый функциональный способ позволяющий добавить обработчик события к указанному элементу и запустить выполнение программы при совершении заданного действия. Получить информацию о сигналах браузера можно из Document (DOM), Element, Window и других объектов поддерживающих события.
addEventListener() является одних из трёх способом прослушивать события, наряду с добавление атрибута к тегам в HTML и обращения к свойствам объекта напрямую.
<!-- добавление атрибута -->
<button onclick="alert('Терпение и труд всё перетрут')">Хочу стать программистом!</button>
<script>{"const myFirstEvent = document.querySelector('button');\n \n // обращаемся к свойству напрямую\n myFirstEvent.onclick = function() { \n alert('Да будет так!');\n }\n \n // используем метод addEventListener\n myFirstEvent.addEventListener('click', function() {\n alert('Дорогу осилит идущий');\n })"}</script>
addEventListener() имеет важное преимущество перед остальными способами, метод позволяет навесить несколько обработчиков на одно событие. Это происходит из-за того, что у объекта только одно свойство, например с именем onclick (клик) или mousemove (движение мыши) и если обратиться к одному из них напрямую несколько раз, второй обработчик перезапишет первый.
В примере выше, как раз можно наблюдать описанный эффект - модальное окно с Да будет так! появится, а вот Терпение и труд всё перетрут нет.
Также отследить некоторые события можно только с помощью addEventListener(), например навесить обработчик на DOMContentLoaded по другому не получиться.
Синтаксис
element.addEventListener(eventType, handler, options);
element - объект, действие по которому отслеживаем.
eventType - тип события, которое мы хотим отследить: клик, прокрутка мыши, нажатие клавиши и т.д. Написание чувствительно к регистру: click правильно, Click или CLICK неправильно.
handler - имя функции или сама функция, которая будет выполнена после наступления события.
options - необязательный объект со свойствами, внутри которого доступны следующие параметры:
capture: значение записывается в форматеtrueилиfalseи задает этап, на котором будет обработано событие. По умолчаниюfalse- на этапе всплытия,true- на этапе погружения (перехват). Если вместоoptionsзадать булево значение - это будет равносильно{capture: false/true}once: значение типаboolean, по умолчаниюfalse, еслиtrueтогда обработчик будет удален после выполнения.passive: по умолчаниюfalse, еслиtrueобработчик никогда не вызоветpreventDefault(), взамен этого будет сгенерировано предупреждение в console.
<button>В скором времени я стану JavaScript middle</button>
<script>{"const clickButton = document.querySelector('button');\n clickButton.addEventListener('click', showMessage, {\n capture: false,\n once: true,\n passive: false,\n })\n \n function showMessage() {\n alert('У тебя все получиться, я в тебя верю!');\n }"}</script>
При клике на кнопку мы получим модальное окно с сообщением, если кликнуть второй раз ничего не произойдет, так как свойство once равно true - после события обработчик удаляется.
removeEventListener()
Удалить обработчик события можно также с помощью метода removeEventListener(). В этом случае появляется возможность сделать это когда нам удобно. Для того, чтобы все сработало, первые два параметра у обоих методов должны быть идентичными. Важно также передать в removeEventListener() именно название функции, с анонимными функциями ничего не получиться, даже если записать код точь в точь.
<button>Удалить обработчик события</button>
<script>{"const clickButton = document.querySelector('button');\n clickButton.addEventListener('click', showMessage);\n \n function showMessage() {\n if (clickButton.innerText === 'Удалить обработчик события') {\n alert('Обработчик удален');\n clickButton.removeEventListener('click', showMessage);\n } else {\n alert('Обработчик не удален');\n }\n }"}</script>
В этом случае, если поменять текст на кнопке обработчик удален не будет.
Объект события
Для более детального представления о том какие действия происходят на странице используют объект события, который создается браузером после совершения действия. Такой объект записывается в качестве первого аргумента функции обработчика, для названия принято использовать event. Это позволяет гибко настраивать отслеживание получая информацию о том какая клавиша была нажата, координаты указателя мыши и другое.
<button class="btn">JavaScript</button>
<script>{"const btnJS = document.querySelector('.btn');\n btnJS.addEventListener('click', showElemObjEvent);\n \n function showElemObjEvent(event) {\n console.log(event.type); // тип события\n console.log(event.target); // элемент на котором произошло событие\n console.log(event.clientX); // координаты курсора по оси X\n console.log(event.clientY); // координаты курсора по оси Y\n console.log(event); // получим весь объект с информацией о событии\n }"}</script>
Популярные события
Рассмотрим события, которые отслеживаются чаще других:
click - клик левой кнопкой мыши по элементу, на сенсорных устройствах это касание;
contextmenu - клик на элемент правой кнопкой мыши - вызов контекстного меню;
mouseover / mouseout - наведение на элемент курсора мыши / курсор покидает элемент;
mousemove - движение мыши;
keydown / keyup - клавиша нажата / клавиша отпущена;
DOMContentLoaded - весь HTML загружен, а DOM-дерево построено.
Для того, чтобы посмотреть все возможные события для DOM-элемента, нажмите правой кнопкой на страницу, далее Просмотреть код, выберите элемент на странице, а далее кликните на Свойства (Properties). В фильтре наберите on, все что начинает на on являются событиями.
Как добавить обработчик на множество элементом
addEventListener и forEach
<button class="myChoice">JavaScript</button>
<button class="myChoice">Python</button>
<script>{"const choice = document.querySelectorAll('.myChoice');\n \n choice.forEach(choiceItem => {\n choiceItem.addEventListener('click', () => answer(choiceItem.innerHTML));\n })\n \n function answer(text) {\n if (text === 'JavaScript') {\n alert('Отличный выбор!');\n } else {\n alert('Возможно вы ошиблись?');\n }\n }"}</script>
В данном примере мы получили все элементы с классом myChoice в объект через querySelectorAll(), а потом с помощью forEach() перебором назначили обработчик события на все кнопки.
Делегирование событий
Вторым и более удачным способом отслеживать события на множестве элементов это делегирование.
<style>{"td {\n border: 1px solid;\n width: 90px;\n height: 90px;\n text-align: center;\n border-color: black;\n }\n \n .hideText {\n color: white;\n }"}</style>
<table>
<td class="hideText">JavaScript</td>
<td class="hideText">React</td>
<td class="hideText">HTML</td>
</table>
<script>{"const getTable = document.querySelector('table');\n \n getTable.addEventListener('click', function(event) {\n if (event.target.closest('.hideText')) {\n event.target.classList.remove('hideText');\n }\n })"}</script>
В этом примере мы назначаем обработчик для родителя в котором содержатся интересующие нас элементы. Далее отслеживаем с помощью event.target.closest(‘.hideText’) было ли взаимодействие с тегом с классом .hideText и если это так удаляем оттуда класс, который делает текст белым.
Всплытие и погружение
Всплытие - это когда обработчик сначала срабатывает на элементе с которым произошло взаимодействие, затем событие обрабатывается на его родителе и далее выше по цепочке.
<body> в четвертую очередь
<span></span> не сработает
<span> в третью очередь
<span> во вторую очередь
<span></span> кликаем сюда - обработчик сработает на этом элементе в первую очередь
</span>
</span>
</body>
Погружение - при взаимодействии с объектом, который находится ниже чем элемент со свойством capture: true, сначала событие будет обработано на последнем, далее обработчик сработает на всех потомках и только потом на всех родителях.
<body> в пятую очередь
<span></span> не сработает
<span> в четвертую очередь
<span> - элемент со свойством capture: true - в первую очередь
<span> - в третью очередь
<span></span> кликаем сюда - обработчик сработает на этом элементе во вторую очередь
</span>
</span>
</span>
</body>
Для того, чтобы понять тему потренируйтесь на примере, наблюдая последовательность выполнения действий при клике на различные элементы. Результат отслеживайте в console.
Пример с квадратами <style>{".square1 {\n width: 600px;\n height: 600px;\n background: red;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n \n .square2 {\n width: 450px;\n height: 450px;\n background: blue;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n \n .square3 {\n width: 350px;\n height: 350px;\n background: yellow;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n \n .square4 {\n width: 250px;\n height: 250px;\n background: white;\n display: flex;\n justify-content: center;\n align-items: center;\n }"}</style>
<div class="square1">
<div class="square2">
<div class="square3">
<div class="square4"></div>
</div>
</div>
</div>
<script>{"const squareFirst = document.querySelector('.square1');\n const squareSecond = document.querySelector('.square2');\n const squareThird = document.querySelector('.square3');\n const squareFourth = document.querySelector('.square4');\n \n squareFirst.addEventListener('click', () => clickSquare('Квадрат №1'));\n squareSecond.addEventListener('click', () => clickSquare('Квадрат №2'));\n squareThird.addEventListener('click', () => clickSquare('Квадрат №3'), { \"capture\": true });\n squareFourth.addEventListener('click', () => clickSquare('Квадрат №4'));\n \n function clickSquare(text) {\n console.log(text);\n }"}</script>
Получаем доступ к элементу через this
Для того, чтобы получить доступ к элементу на котором висит обработчик, в функции можно использовать this.
<button class="btn">После того, как выучу JS примусь за React</button>
<script>{"const getButton = document.querySelector('.btn');\n getButton.addEventListener('click', printBtnText);\n \n function printBtnText() {\n alert(this.innerHTML);\n }"}</script>
Итого
Обработчик события это важный элемент в JavaScript, именно с помощью него можно отслеживать действия пользователя на странице. В свою очередь метод addEventListener() является основным способом для назначения таких обработчиков объектам.
Удалить обработчик события после использования можно двумя способами: с помощью свойства once со значением true или метода removeEventListener().
Для того, чтобы получить более подробную информацию о событии используют объект события, который передается первым аргументом в функцию. Отсюда можно получить координаты клика, какая кнопка была нажата и многое другое.
Для того, чтобы назначить обработчик множеству элементов используют принцип делегирования - событие фиксируется не только на элементе которому был назначен обработчик, но и на всех вложенных. Второй способ - это навешивание обработчиков через цикл forEach().