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

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

В этой статье мы рассмотрим различные способы, с помощью которых Вы можете подписаться на события элементов веб-страницы. Один из способов основан на использовании атрибутов HTML, два других способа осуществляются через код JavaScript посредством свойства on[event] или метода addEventListener().

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Например:

<script>
  // функция sum
  function sum() {
    let number1 = +document.querySelector('#number1').value;
    let number2 = +document.querySelector('#number2').value;
    let sum = number1 + number2;
    document.querySelector('#answer').value = 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:

<!-- HTML код кнопки -->
<button type="button" id="my-btn">

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

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

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

Например:

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 код кнопок -->
<button type="button">Кнопка 1</button>
<button type="button">Кнопка 2</button>
<button type="button">Кнопка 3</button>

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

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

Например:

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

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

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

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

<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>

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

<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, в этом случае он будет просто определять фазу (всплытие или погружение).

Пример:

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.

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

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

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

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

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);

Задачи

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>
Решение

Как правильно работать с событиями

Работать в JavaScript с документом HTML (DOM-деревом) и обрабатывать события необходимо только после того страница полностью загрузится:

//когда вся страница загрузилась, вызываем нашу функцию pageInit
window.addEventListener( "load", pageInit);
//функция pageInit()
function pageInit() {
  //подписываемся на события
}

Вышеприведенный код можно записать более кратко, с помощью анонимной функции:

window.addEventListener( "load", function() {
//подписываемся на события
}

Более правильно работать не с событием load (происходит после полной загрузки страницы), а с событием DOMContentLoaded, которое происходит после того как браузер загрузил документ HTML и построил DOM-дерево. Т.е. для того чтобы работать с DOM-деревом нет необходимости ждать пока загрузятся все ресурсы HTML-страницы достаточно чтобы браузер построил дерево DOM.

//HTML документ загрузился и дерево DOM построено
document.addEventListener( "DOMContentLoaded", pageInit);
//функция pageInit()
function pageInit() {
  //подписываемся на события
}

Вышеприведенный код можно записать более кратко, с помощью анонимной функции:

document.addEventListener( "DOMContentLoaded", function() {
  //подписываемся на события
}

Одновременно подписать на событие сразу несколько объектов

Например, подписать на событие click сразу все элементы p. Обработку события выполнять с помощью функции myFunction():

document.addEventListener( "DOMContentLoaded", function() {
  var elementsP = document.getElementsByTagName("P");
  for (var i=0; i < elementsP.length, i++) {
    elementsP[i].addEventListener("click", myFunction);
  }
}
//функция myFunction()
function myFunction() {
  //...
}

Комментарии ()

    Войдите, пожайлуста, в аккаунт, чтобы оставить комментарий.