JavaScript – Введение в события. Обработчик события

JavaScript – Введение в события. Обработчик события
Содержание:
  1. Что такое событие?
  2. Обработчик события
  3. Способы задания событию обработчика
  4. Инициализация обработчика через атрибут
  5. Добавление обработчика через свойство DOM объекта
  6. Подписка на событие через addEventListener
  7. Задачи
  8. Комментарии

В этой статье вы узнаете: что такое событие, способы задания обработчика (слушателя) событию, методы addEventListener и removeEventListener.

Что такое событие?

Событие – это определённый сигнал от браузера. Он сообщает нам о том, что что-то произошло.

Например: щелчок мыши, нажатие клавиши на клавиатуре, изменение размера области просмотра, завершение загрузки документа и т.д.

При этом сигнал всегда связан с объектом. Подавать сигналы могут различные объекты: window, document, DOM-элементы и т.д.

Список некоторых событий и их название:

  • DOMContentLoaded – завершение загрузки DOM;
  • click – клик (нажатие левой кнопки мыши, на устройствах с сенсорным управлением возникает при касании);
  • keydown – нажатие клавиши на клавиатуре;
  • resize – изменение размеров документа;
  • change – окончание изменения значения в поле ввода.

Обработчик события

Зачем нам события? Они нам нужны для того, чтобы мы могли реагировать на них, или другими словами выполнять определённые действия, когда они произойдут.

В JavaScript это выполняется посредством привязывания некоторой функции к событию. После этого эта функция будет вызываться всякий раз, когда это событие на указанном элементе будет возникать. Эту функцию в JavaScript принято называть обработчиком события.

Следует отметить, что на странице постоянно возникает огромное количество событий, независимо от того назначили ли мы им обработчик или нет. Наша задача – это заставить наш сайт или приложение реагировать только на те события, которые нам небезразличны.

Способы задания событию обработчика

Назначить обработчик событию можно разными способами:

  • через HTML-атрибут on{событие} (не является хорошей практикой);
  • посредством свойства DOM-элемента on{событие};
  • используя специальный метод addEventListener.

Инициализация обработчика через атрибут

Этот способ позволяет прописать обработчик напрямую в разметке. Выполняется это посредством указания JavaScript кода в атрибуте on{событие}. Вместо {событие} необходимо написать имя (тип) события (например: click).

Пример, в котором назначим HTML-элементу button обработчик события click, используя атрибут:

HTML
<!-- onclick - атрибут, содержащий код, который будет выполняться всякий раз при наступлении события click на этом элементе -->
<button type="button" onclick="alert(Date())">Текущая дата</button>

Если код, который нужно поместить в атрибут достаточно большой, то в этом случае его лучше оформить в виде функции, а в атрибут поместить её вызов.

Например:

HTML
<script>
  // функция sum
  function sum() {
    const number1 = +document.querySelector('#number1').value;
    const number2 = +document.querySelector('#number2').value;
    const sum = number1 + number2;
    document.querySelector('#answer').textContent = sum;
  }
</script>

<input type="text" id="number1">
<input type="text" id="number2">
<div id="answer"></div>
<button type="button" onclick="sum()">Посчитать</button>

В этом примере мы указали в качестве обработчика функцию sum.

При этом задавать обработчик напрямую в разметке не является хорошей практикой, т.к. это приведёт к смешиванию JavaScript и HTML кода.

Добавление обработчика через свойство DOM объекта

Второй способ назначить обработчик - это использовать свойство on{событие}.

Например, привяжем обработчик события click к элементу (для этого события свойство будет onclick):

JavaScript
<!-- HTML код кнопки -->
<button type="button" id="my-btn">Нажми на меня</button>

<!-- Скрипт на JavaScript -->
<script>
// получим кнопку и сохраним ссылку на неё в переменную
const $btn = document.querySelector('#my-btn');
// добавим к $btn обработчик события click
$btn.onclick = function() {
  alert('Вы кликнули на кнопку!');
}
</script>

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

Другой вариант – это назначить уже существующую функцию.

Например:

JavaScript
function changeBgColor() {
  document.body.style.backgroundColor = `rgb(${Math.round(Math.random()*255)}, ${Math.round(Math.random()*255)}, ${Math.round(Math.random()*255)})`;
}

document.onclick = changeBgColor;

Внутри обработчика можно обратиться к текущему элементу, т.е. к тому для которого в данный момент был вызван этот обработчик. Осуществляется это с помощью ключевого слова this.

Например:

HTML
<!-- HTML код кнопок -->
<button type="button">Кнопка 1</button>
<button type="button">Кнопка 2</button>
<button type="button">Кнопка 3</button>

<!-- Скрипт на JavaScript -->
<script>
function message() {
  // this - обращаемся к кнопке для которой вызван обработчик
  alert(this.textContent);
}
// получим кнопки и сохраним ссылки на них в переменную $btns
const $btns = document.querySelectorAll('button');
// переберём кнопки и добавим к ним обработчик, используя onclick
$btns.forEach(function($element) {
  $element.onclick = message;
});
</script>

Кстати, когда обработчик задаётся через атрибут, то браузер самостоятельно при чтении такого HTML создаёт из значения этого атрибута функцию и присваивает её одноименному свойству этого элемента.

Например:

HTML
<button id="btn" type="button" onclick="alert('Вы кликнули на кнопку')">Кнопка</button>

<script>
const $element = document.querySelector('#btn');
// получим значение свойства onclick (как видно браузер туда автоматически записал функцию, которую создал на основании содержимого этого атрибута)
console.log($element.onclick);
</script>
Значение свойства onclick DOM-элемента

Т.е., по сути, задание свойства через атрибут – это просто способ инициализации обработчика. Т.к. сам обработчик в этом случае тоже хранится в свойстве DOM-объекта.

Но установка обработчика через свойство имеет недостаток. С помощью него нельзя назначить одному событию несколько обработчиков. Если в коде создадим новый обработчик, то он перезапишет существующий:

JavaScript
<button id="btn" type="button">Кнопка</button>

<script>
  const $element = document.querySelector('#btn');

  $element.onclick = function () {
    alert(`id = ${this.id}`);
  }
  // заменит предыдущий обработчик
  $element.onclick = function () {
    alert(`text = ${this.textContent}`);
  }
</script>

Кстати, также не получится назначить несколько обработчиков, один через атрибут, а другой через свойство. Последний перепишет предыдущий.

HTML
<button id="btn" type="button" onclick="alert(`id = ${this.id}`);">Кнопка</button>

<script>
  const $element = document.querySelector('#btn');
  // заменит обработчик, инициализированный с помощью атрибута
  $element.onclick = function () {
    alert(`text = ${this.textContent}`);
  }
</script>

Подписка на событие через addEventListener

Ещё один способ назначить событию обработчик — это использовать метод addEventListener.

Синтаксис addEventListener:

// $element - объект или DOM-элемент к которому нужно добавить обработчик
$element.addEventListener(event, handler[, options]);

Параметры:

  • event - имя события (например, click);
  • handler - функция, которая будет вызвана при возникновении этого события;;
  • options (не обязательный) - объект, в котором можно задать дополнительные параметры.

В options можно задать:

  • once - если true, то обработчик будет вызван всего один раз;
  • capture - задаёт фазу, на которой нужно вызвать обработчик события (по умолчанию - на этапе всплытия); если нужно на этапе погружения (перехвата) - то этому ключу следует установить значение true;
  • passive - определяет, следует ли вызывать preventDefault(); если установить true - то обработчик никогда не вызовет этот метод.

Кроме этого, options можно установить true или false, в этом случае он будет просто определять фазу (всплытие или погружение).

Пример:

JavaScript
function changeBgColor() {
  document.body.style.backgroundColor = '#3f51b5';
}

document.addEventListener('click', changeBgColor, false);

В этом примере addEventListener прикреплен к объекту document. Когда событие click возникнет на этом элементе, будет вызвана функция changeBgColor.

Если мы откроем документ, содержащий этот код в браузере, то сначала увидим пустую страницу.

JavaScript - Страница до клика по ней

Однако при клике фон страницы изменится с белого на #3f51b5.

JavaScript - Страница после клика по ней

Иногда возникают ситуации, когда нужно удалить обработчик. Это можно выполнить, используя removeEventListener:

$element.removeEventListener(event, handler[, options]);

Этот метод принимает аргументы тех же типов, что addEventListener.

При этом чтобы, удалить обработчик, нам нужно указать точно такие же аргументы, которые мы использовали при его назначении.

JavaScript

function changeBgColor() {
  document.body.style.backgroundColor = '#3f51b5';
}

document.addEventListener('click', changeBgColor, false);
document.removeEventListener('click', changeBgColor, false);

Если обработчик - анонимная функция, то её удалить нельзя.

JavaScript

document.addEventListener('click', function() {
  document.body.style.backgroundColor = '#3f51b5';
});
// удалить обработчик установленный выше с помощью addEventListener не получится, т.к. это разные функции, имеющие одинаковый код
document.removeEventListener('click', function() {
  document.body.style.backgroundColor = '#3f51b5';
});

Как добавить несколько обработчиков к событию?

Метод addEventListener в отличие от предыдущих способов позволяет назначить одному событию несколько обработчиков:

function handler1() { ... }
function handler2() { ... }

document.addEventListener('click', handler1);
document.addEventListener('click', handler2);

Как правильно прикрепить обработчики к элементам?

Для прикрепления обработчиков к элементам, необходимо чтобы эти элементы на странице были доступны. Определить, когда они будут доступны с момента загрузки документам можно с помощью события DOMContentLoaded. Данное событие возникает на document когда DOM полностью построено:

document.addEventListener('DOMContentLoaded', function () {
  // DOM полностью построен и доступен
  ...
});

Задачи

1. Скрыть элемент по нажатию кнопки с классом spoiler-trigger

Написать JavaScript код, который при нажатии на кнопку spoiler-trigger будет скрывать элемент, расположенный сразу за ней. При этом на странице таких кнопок может быть несколько.

JavaScript - Страница до клика по ней
<style>
.hide {
  display: none;
}
</style>

<button class="spoiler-trigger">Скрыть/показать контент</button>
<div>...</div>
...
<button class="spoiler-trigger">Скрыть/показать контент</button>
<div>...</div>
Решение

2. Создать выпадающее меню

Имеется следующая разметка (стили добавлять не нужно, они имеются в примере):

JavaScript
<div class="dropdown">
  <button class="dropdown__trigger">Меню</button>
  <div class="dropdown__content">
    <a href="#">Ссылка 1</a>
    <a href="#">Ссылка 2</a>
    <a href="#">Ссылка 3</a>
  </div>
</div>
JavaScript - Выпадающее меню

Необходимо написать скрипт, который будет при нажатии на кнопку (.dropdown__trigger) переключался класс show у элемента .dropdown:

JavaScript - Открытое выпадающее меню Решение

Комментарии: 0