Обработчики событий в js (как работает addeventlistener)

Опция «passive» для обработчика

Необязательная опция для сигнализирует браузеру, что обработчик не собирается выполнять .

Почему это может быть полезно?

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

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

Опция сообщает браузеру, что обработчик не собирается отменять прокрутку. Тогда браузер начинает её немедленно, обеспечивая максимально плавный интерфейс, параллельно обрабатывая событие.

Для некоторых браузеров (Firefox, Chrome) опция по умолчанию включена в для таких событий, как и .

Объект «событие» (event)

Объект событие всегда передается обработчику и содержит массу полезной информации о том где и какое событие произошло.

Способов передачи этого объекта обработчику существует ровно два, и они зависят от способа его установки и от браузера.

В браузерах, работающих по рекомендациям W3C, объект события всегда передается в обработчик первым параметром.

Например:

function doSomething(event) {
	// event - будет содержать объект события
}

element.onclick = doSomething;

При вызове обработчика объект события будет передан ему первым аргументом.

Можно назначить и вот так:

element.onclick = function(event) {
	// event - объект события
}

Интересный побочный эффект — в возможности использования переменной при назначении обработчика в HTML:

<input type="button" onclick="alert(event)" value="Жми сюда не ошибешься"/>

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

В Internet Explorer существует глобальный объект , который хранит в себе информацию о последнем событии. А первого аргумента обработчика просто нет.

То есть, все должно работать так:

// обработчик без аргументов
function doSomething() {
	// window.event - объект события
}

element.onclick = doSomething;

Обратите внимание, что доступ к при назначении обработчика в HTML (см. пример выше) по-прежнему будет работать

Такой вот надежный и простой кросс-браузерный доступ к объекту события.

Можно кросс-браузерно получить объект события, использовав такой приём:

function doSomething(event) {
    event = event || window.event

    // Теперь event - объект события во всех браузерах.
}

element.onclick = doSomething

Как мы уже говорили раньше, при описании обработчика события в HTML-разметке для получения события можно использовать переменную с названием .

<input type="button" onclick="alert(event.type)" value="Нажми меня"/>

Этот код в действии:

Это совершенно кросс-браузерный способ, так как по стандарту — название первого аргумента функции-обработчика, которую автоматом создаст браузер; ну а в IE значение будет взято из глобального объекта .

Обработчики событий JS (выносим логику коллбэк функции за пределы метода addEventListener)

Мы также можем вынести нашу коллбэк функцию за пределы метода addEventListener,
а внутри обработчика событий просто ссылаться на нее:

1const button =document.querySelector('.btn');

2

3functionhandleClick(){

4console.log('click');

5}

6button.addEventListener('click', handleClick);

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

Давайте использовать готовую логику в функции handleClick — для новой кнопки:

1<div class="wrapper">

2<button class="btn">Click<button>

3<button class="btnTwo">Click2<button>

4<div>
1const button =document.querySelector('.btn');

2const buttonTwo =document.querySelector('.btnTwo');

3

4functionhandleClick(){

5console.log('click');

6}

7button.addEventListener('click', handleClick);

8

9

10buttonTwo.addEventListener('click', handleClick);

addEventListener() Syntax

Here’s the syntax:

  • target: the HTML element you wish to add your event handler to. This element exists as part of the Document Object Model (DOM) and you may wish to learn about .
  • event: a string that specifies the name of the event. We already mentioned and events. For the curious, here’s a full list of HTML DOM events.
  • function: specifies the function to run when the event is detected. This is the magic that can allow your web pages to change dynamically.
  • useCapture: an optional Boolean value (true or false) that specifies whether the event should be executed in the capturing or bubbling phase. In the case of nested HTML elements (such as an within a ) with attached event handlers, this value determines which event gets executed first. By default, it’s set to false which means that the innermost HTML event handler is executed first (bubbling phase).

Всплывающие события или захват событий?

Есть два способа распространения событий в HTML DOM: восходящая и захватывающая.

Распространение событий — это способ определения порядка элементов при возникновении события. Если у вас есть элемент <p> внутри элемента <div>, и пользователь щелкает по элементу <p&gt, событие «click» какого элемента должно быть обработано первым?

При восходящей цепочке сначала обрабатывается событие самого внутреннего элемента, а затем внешнее: сначала обрабатывается событие щелчка элемента <p>, затем событие щелчка элемента <div>.

При захвате сначала обрабатывается событие самого внешнего элемента, а затем внутреннее: сначала обрабатывается событие щелчка элемента <div>, затем событие щелчка элемента <p>.

С помощью метода addEventListener() вы можете указать тип распространения, используя параметр «useCapture»:

addEventListener(event, function, useCapture);

Значение по умолчанию — false, при котором будет использоваться восходящее распространение, когда значение установлено в true, событие использует распространение захвата.

Пример

document.getElementById(«myP»).addEventListener(«click», myFunction, true);
document.getElementById(«myDiv»).addEventListener(«click», myFunction, true);

event.target

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

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

Отличия от (=):

  • – это «целевой» элемент, на котором произошло событие, в процессе всплытия он неизменен.
  • – это «текущий» элемент, до которого дошло всплытие, на нём сейчас выполняется обработчик.

Например, если стоит только один обработчик , то он «поймает» все клики внутри формы. Где бы ни был клик внутри – он всплывёт до элемента , на котором сработает обработчик.

При этом внутри обработчика :

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

Попробуйте сами:

Результат
script.js
example.css
index.html

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

JavaScript

JS Array
concat()
constructor
copyWithin()
entries()
every()
fill()
filter()
find()
findIndex()
forEach()
from()
includes()
indexOf()
isArray()
join()
keys()
length
lastIndexOf()
map()
pop()
prototype
push()
reduce()
reduceRight()
reverse()
shift()
slice()
some()
sort()
splice()
toString()
unshift()
valueOf()

JS Boolean
constructor
prototype
toString()
valueOf()

JS Classes
constructor()
extends
static
super

JS Date
constructor
getDate()
getDay()
getFullYear()
getHours()
getMilliseconds()
getMinutes()
getMonth()
getSeconds()
getTime()
getTimezoneOffset()
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCHours()
getUTCMilliseconds()
getUTCMinutes()
getUTCMonth()
getUTCSeconds()
now()
parse()
prototype
setDate()
setFullYear()
setHours()
setMilliseconds()
setMinutes()
setMonth()
setSeconds()
setTime()
setUTCDate()
setUTCFullYear()
setUTCHours()
setUTCMilliseconds()
setUTCMinutes()
setUTCMonth()
setUTCSeconds()
toDateString()
toISOString()
toJSON()
toLocaleDateString()
toLocaleTimeString()
toLocaleString()
toString()
toTimeString()
toUTCString()
UTC()
valueOf()

JS Error
name
message

JS Global
decodeURI()
decodeURIComponent()
encodeURI()
encodeURIComponent()
escape()
eval()
Infinity
isFinite()
isNaN()
NaN
Number()
parseFloat()
parseInt()
String()
undefined
unescape()

JS JSON
parse()
stringify()

JS Math
abs()
acos()
acosh()
asin()
asinh()
atan()
atan2()
atanh()
cbrt()
ceil()
clz32()
cos()
cosh()
E
exp()
expm1()
floor()
fround()
LN2
LN10
log()
log10()
log1p()
log2()
LOG2E
LOG10E
max()
min()
PI
pow()
random()
round()
sign()
sin()
sinh()
sqrt()
SQRT1_2
SQRT2
tan()
tanh()
trunc()

JS Number
constructor
isFinite()
isInteger()
isNaN()
isSafeInteger()
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
NaN
POSITIVE_INFINITY
prototype
toExponential()
toFixed()
toLocaleString()
toPrecision()
toString()
valueOf()

JS OperatorsJS RegExp
Modifiers:
g
i
m
Groups:

(x|y)
Metacharacters:
.
\w
\W
\d
\D
\s
\S
\b
\B
\0
\n
\f
\r
\t
\v
\xxx
\xdd
\uxxxx
Quantifiers:
+
*
?
{X}
{X,Y}
{X,}
$
^
?=
?!
Properties:
constructor
global
ignoreCase
lastIndex
multiline
source
Methods:
compile()
exec()
test()
toString()

JS Statements
break
class
continue
debugger
do…while
for
for…in
for…of
function
if…else
return
switch
throw
try…catch
var
while

JS String
charAt()
charCodeAt()
concat()
constructor
endsWith()
fromCharCode()
includes()
indexOf()
lastIndexOf()
length
localeCompare()
match()
prototype
repeat()
replace()
search()
slice()
split()
startsWith()
substr()
substring()
toLocaleLowerCase()
toLocaleUpperCase()
toLowerCase()
toString()
toUpperCase()
trim()
valueOf()

Description and Syntax

To attach a JavaScript event handler to a specific element, you have to use the JavaScript method.

This method is specifically used to attach an event handler to a specified element in a way that doesn’t overwrite other present event handlers. Multiple event handlers may be applied to a single element (for example, two click events might be assigned to the same element).

Any DOM object may be assigned a JavaScript event handler, which includes not only HTML elements, but, for example, the window itself as well.

The JavaScript method can also make it easier to control the way an event reacts to bubbling.

JavaScript is separated from the markup of HTML when using the JavaScript to improve readability, and will even allow adding event listeners without the control of the HTML markup. By using the method, event handlers can be easily removed:

Example Copy

Syntax

Let’s now look at the rules of syntax that apply and make sure we understand the parameters required:

We’ll now explain it to you step by step:

  • The first parameter specifies the event type (e.g. or ).
  • The second parameter defines the function to be called and executed when the event occurs.
  • The optional third parameter is a boolean value using which you may specify whether to use event capturing or bubbling.

Действия по умолчанию

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

Для большинства типов событий обработчики JavaScript event вызываются до выполнения действий по умолчанию. Если не нужно, чтобы выполнялось поведение по умолчанию, нужно вызвать для объекта события метод preventDefault.

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

<a href="https://developer.mozilla.org/">MDN</a>
<script>
  var link = document.querySelector("a");
  link.addEventListener("click", function(event) {
    console.log("Nope.");
    event.preventDefault();
  });
</script>

Старайтесь не делать так, если у вас нет на это веских причин.

В зависимости от браузера некоторые события не могут быть перехвачены. В Google Chrome, например, сочетание клавиш (event keycode JavaScript) для закрытия текущей вкладки (Ctrl-W или Command-W) не может быть обработано с помощью JavaScript.

addEventListener

Фундаментальный недостаток описанных выше способов назначения обработчика – невозможность повесить несколько обработчиков на одно событие.

Например, одна часть кода хочет при клике на кнопку делать её подсвеченной, а другая – выдавать сообщение.

Мы хотим назначить два обработчика для этого. Но новое DOM-свойство перезапишет предыдущее:

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

Синтаксис добавления обработчика:

Имя события, например .
Ссылка на функцию-обработчик.
Дополнительный объект со свойствами:

  • : если , тогда обработчик будет автоматически удалён после выполнения.
  • : фаза, на которой должен сработать обработчик, подробнее об этом будет рассказано в главе Всплытие и погружение. Так исторически сложилось, что может быть , это то же самое, что .
  • : если , то указывает, что обработчик никогда не вызовет , подробнее об этом будет рассказано в главе Действия браузера по умолчанию.

Для удаления обработчика следует использовать :

Удаление требует именно ту же функцию

Для удаления нужно передать именно ту функцию-обработчик которая была назначена.

Вот так не сработает:

Обработчик не будет удалён, т.к

в передана не та же функция, а другая, с одинаковым кодом, но это не важно

Вот так правильно:

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

Метод позволяет добавлять несколько обработчиков на одно событие одного элемента, например:

Как видно из примера выше, можно одновременно назначать обработчики и через DOM-свойство и через . Однако, во избежание путаницы, рекомендуется выбрать один способ.

Обработчики некоторых событий можно назначать только через

Существуют события, которые нельзя назначить через DOM-свойство, но можно через .

Например, таково событие , которое срабатывает, когда завершена загрузка и построение DOM документа.

Так что более универсален. Хотя заметим, что таких событий меньшинство, это скорее исключение, чем правило.

Пример № 1 — Вызов addEventListener() с двумя параметрами (минимальный набор для вызова)

Разметка такая:

<body>
   <h1>Пример 01</h1>
   <p>Вызов addEventListener() с двумя параметрами (минимальный набор для вызова)</p>
</body>

Получим элемент H1 в переменную:

var elh1 = document.getElementsByTagName("h1")

Добавляем слушатель события для элемента H1:

elh1.addEventListener("click", () => console.log("Клик был совершён на элементе h1"))

Пример 01 — Кликнули по заголовку h1 — Увидели запись в консоли — JavaScript

Сейчас мы можем добавить ещё один слушатель событий. Предлагаю на этот раз передать в функцию сам объект события и посмотреть из чего он состоит:

elh1.addEventListener("click", (event) => console.log(event))

Пример 01 — Кликнули по заголовку h1 — Увидели объект события в консоли — JavaScript

Обратите внимание. Мы выполнили сразу две задачи при одном клике на одном элементе h1

  • Первый результат — вывод в консоль строки.
  • Второй результат — вывод в консоль объекта события.

Если сейчас посмотреть на синтаксис метода addEventListener() ещё раз, то:

  • target — это объект h1 текущего документа, который является целью события
  • type — это значение «click» атрибута у события.
  • callback — анонимная функция, которая будет вызываться при  ., которая выведет в консоль объект события.

JS Учебник

JS ГлавнаяJS ВведениеJS Что? Где? Куда?JS ВыводJS ЗаявленияJS СинтаксисJS КомментарииJS ПеременныеJS ОператорыJS АрифметикаJS ПрисваиванияJS Типы данныхJS ФункцииJS ОбъектыJS СобытияJS СтрокиJS Методы строкJS ЧислаJS Методы чиселJS МассивыJS Методы массиваJS Сортировка массиваJS Итерация массиваJS Объекты датJS Формат датJS Метод получения датJS Метод набора датJS Математические…JS Случайные числаJS БулевыJS Сравнение…JS Заявления if…elseJS Заявление switchJS Цикл forJS Цикл whileJS Заявление break…JS Преобразование…JS Битовые…JS Регулярные выраженияJS ОшибкиJS ОбластьJS ПодъемныйJS СтрогийJS Ключевое слово thisJS Ключевое слово letJS КонстантыJS Функция стрелкиJS КлассыJS ОтладчикJS Руководство стиляJS ПрактикаJS Распространенные ошибкиJS ЭффективностьJS Зарезервированные словаJS ВерсииJS Версия ES5JS Версия ES6JS Версия 2016JS Версия 2017JS JSON

Метод addEventListener()

Пример

Добавьте прослушиватель событий, который запускается, когда пользователь нажимает кнопку:

document.getElementById(«myBtn»).addEventListener(«click», displayDate);

Метод придает обработчик события для указанного элемента.

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

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

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

Вы можете добавить слушателей событий к любому объекту DOM, а не только к элементам HTML. т.е. window объект.

Метод упрощает управление реакцией события на восходящую цепочку.

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

Вы можете легко удалить прослушиватель событий с помощью метода.

Всплытие

Основной принцип всплытия:

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

Например, есть 3 вложенных элемента , с обработчиком на каждом:

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

Поэтому если в примере выше кликнуть на , то последовательно выведутся : → → .

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

Всплывают почти все события.

Ключевое слово в этой фразе – «почти».

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

События и узлы DOM

Каждый обработчик событий браузера регистрируется в контексте. При вызове функции addEventListener она вызывается как метод для всего окна, так как в браузере глобальный диапазон эквивалентен объекту window. Каждый элемент DOM имеет свой собственный метод addEventListener, который позволяет отслеживать события именно в этом элементе:

<button>Нажмите на меня</button>
<p>Здесь нет обработчика.</p>
<script>
  var button = document.querySelector("button");
  button.addEventListener("click", function() {
    console.log("Button clicked.");
  });
</script>

В данном примере обработчик подключен к узлу кнопки. JavaScript mouse events приводит в действие обработчик, а клик в остальной части документа — нет.

Установив для узла атрибут onclick, мы получим тот же результат. Но узел имеет только один атрибут onclick, поэтому можно зарегистрировать для каждого узла только один обработчик. Метод addEventListener позволяет добавлять любое количество обработчиков. Так мы застрахованы от случайной замены обработчика, который уже был зарегистрирован.

Метод removeEventListener, вызывается с аргументами, аналогичными addEventListener. Он удаляет обработчик:

<button>Одноразовая кнопка</button>
<script>
  var button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>

Чтобы отменить функцию обработчика, мы задаем для нее имя (например, once). Так мы передаем ее как в addEventListener, так и в removeEventListener.

addEventListener

The fundamental problem of the aforementioned ways to assign handlers – we can’t assign multiple handlers to one event.

Let’s say, one part of our code wants to highlight a button on click, and another one wants to show a message on the same click.

We’d like to assign two event handlers for that. But a new DOM property will overwrite the existing one:

Developers of web standards understood that long ago and suggested an alternative way of managing handlers using special methods and . They are free of such a problem.

The syntax to add a handler:

Event name, e.g. .
The handler function.
An additional optional object with properties:

  • : if , then the listener is automatically removed after it triggers.
  • : the phase where to handle the event, to be covered later in the chapter Bubbling and capturing. For historical reasons, can also be , that’s the same as .
  • : if , then the handler will not call , we’ll explain that later in Browser default actions.

To remove the handler, use :

Removal requires the same function

To remove a handler we should pass exactly the same function as was assigned.

This doesn’t work:

The handler won’t be removed, because gets another function – with the same code, but that doesn’t matter, as it’s a different function object.

Here’s the right way:

Please note – if we don’t store the function in a variable, then we can’t remove it. There’s no way to “read back” handlers assigned by .

Multiple calls to allow to add multiple handlers, like this:

As we can see in the example above, we can set handlers both using a DOM-property and . But generally we use only one of these ways.

For some events, handlers only work with

There exist events that can’t be assigned via a DOM-property. Only with .

For instance, the event, that triggers when the document is loaded and DOM is built.

So is more universal. Although, such events are an exception rather than the rule.

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

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

Функция должна быть присвоена как , а не .

Если добавить скобки, то – это уже вызов функции, результат которого (равный , так как функция ничего не возвращает) будет присвоен . Так что это не будет работать.

…А вот в разметке, в отличие от свойства, скобки нужны:

Это различие просто объяснить. При создании обработчика браузером из атрибута, он автоматически создаёт функцию с телом из значения атрибута: .

Так что разметка генерирует такое свойство:

Используйте именно функции, а не строки.

Назначение обработчика строкой также сработает. Это сделано из соображений совместимости, но делать так не рекомендуется.

Не используйте для обработчиков.

Такой вызов работать не будет:

Регистр DOM-свойства имеет значение.

Используйте , а не , потому что DOM-свойства чувствительны к регистру.

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

Событию можно назначить обработчик, то есть функцию, которая сработает, как только событие произошло.

Именно благодаря обработчикам JavaScript-код может реагировать на действия пользователя.

Есть несколько способов назначить событию обработчик. Сейчас мы их рассмотрим, начиная с самого простого.

Обработчик может быть назначен прямо в разметке, в атрибуте, который называется .

Например, чтобы назначить обработчик события на элементе , можно использовать атрибут , вот так:

При клике мышкой на кнопке выполнится код, указанный в атрибуте .

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

Атрибут HTML-тега – не самое удобное место для написания большого количества кода, поэтому лучше создать отдельную JavaScript-функцию и вызвать её там.

Следующий пример по клику запускает функцию :

Как мы помним, атрибут HTML-тега не чувствителен к регистру, поэтому будет работать так же, как и … Но, как правило, атрибуты пишут в нижнем регистре: .

Можно назначать обработчик, используя свойство DOM-элемента .

К примеру, :

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

Этот способ, по сути, аналогичен предыдущему.

Обработчик всегда хранится в свойстве DOM-объекта, а атрибут – лишь один из способов его инициализации.

Эти два примера кода работают одинаково:

  1. Только HTML:

  2. HTML + JS:

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

В примере ниже назначение через JavaScript перезапишет обработчик из атрибута:

Кстати, обработчиком можно назначить и уже существующую функцию:

Убрать обработчик можно назначением .

Итого

Чтобы сгенерировать событие из кода, вначале надо создать объект события.

Базовый конструктор принимает обязательное имя события и – объект с двумя свойствами:

  • чтобы событие всплывало.
  • если мы хотим, чтобы работал.

Особые конструкторы встроенных событий , и другие принимают специфичные для каждого конкретного типа событий свойства. Например, для событий мыши.

Для пользовательских событий стоит применять конструктор . У него есть дополнительная опция , с помощью которой можно передавать информацию в объекте события. После чего все обработчики смогут получить к ней доступ через .

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

Весьма часто, когда разработчик хочет сгенерировать встроенное событие – это вызвано «кривой» архитектурой кода.

Как правило, генерация встроенных событий полезна в следующих случаях:

  • Либо как явный и грубый хак, чтобы заставить работать сторонние библиотеки, в которых не предусмотрены другие средства взаимодействия.
  • Либо для автоматического тестирования, чтобы скриптом «нажать на кнопку» и посмотреть, произошло ли нужное действие.

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

Итого

События загрузки страницы:

  • генерируется на , когда DOM готов. Мы можем применить JavaScript к элементам на данном этапе.

    • Скрипты, вроде или блокируют DOMContentLoaded, браузер ждёт, пока они выполнятся.
    • Изображения и другие ресурсы тоже всё ещё могут продолжать загружаться.
  • Событие на генерируется, когда страница и все ресурсы загружены. Мы редко его используем, потому что обычно нет нужды ждать так долго.
  • Событие на генерируется, когда пользователь покидает страницу. Если мы отменим событие, браузер спросит, на самом ли деле пользователь хочет уйти (например, у нас есть несохранённые изменения).
  • Событие на генерируется, когда пользователь окончательно уходит, в обработчике мы можем делать только простые вещи, которые ни о чём не спрашивают пользователя и не заставляют его ждать. Из-за этих ограничений оно редко используется. Мы можем послать сетевой запрос с помощью .
  • – текущее состояние документа, изменения можно отследить с помощью события :

    • – документ грузится.
    • – документ прочитан, происходит примерно в то же время, что и , но до него.
    • – документ и ресурсы загружены, происходит примерно в то же время, что и , но до него.

Итого

При наступлении события – самый глубоко вложенный элемент, на котором оно произошло, помечается как «целевой» ().

  • Затем событие сначала двигается вниз от корня документа к , по пути вызывая обработчики, поставленные через , где – это сокращение для .
  • Далее обработчики вызываются на целевом элементе.
  • Далее событие двигается от вверх к корню документа, по пути вызывая обработчики, поставленные через и без третьего аргумента или с третьим аргументом равным .

Каждый обработчик имеет доступ к свойствам события :

  • – самый глубокий элемент, на котором произошло событие.
  • (=) – элемент, на котором в данный момент сработал обработчик (тот, на котором «висит» конкретный обработчик)
  • – на какой фазе он сработал (погружение=1, фаза цели=2, всплытие=3).

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

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

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

Тоже самое справедливо для обработчиков событий. Код, который «навесил» обработчик на конкретный элемент, знает максимум деталей об элементе и его предназначении. Например, обработчик на определённом скорее всего подходит только для этого конкретного , он знает все о нём, поэтому он должен отработать первым. Далее имеет смысл передать обработку события родителю – он тоже понимает, что происходит, но уже менее детально, далее – выше, и так далее, до самого объекта , обработчик на котором реализовывает самую общую функциональность уровня документа.

Всплытие и погружение являются основой для «делегирования событий» – очень мощного приёма обработки событий. Его мы изучим в следующей главе.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector