Javascript событие что это
Перейти к содержимому

Javascript событие что это

  • автор:

Введение в браузерные события

Событие – это сигнал от браузера о том, что что-то произошло. Все DOM-узлы подают такие сигналы (хотя события бывают и не только в DOM).

Вот список самых часто используемых DOM-событий, пока просто для ознакомления:

События мыши:

  • click – происходит, когда кликнули на элемент левой кнопкой мыши (на устройствах с сенсорными экранами оно происходит при касании).
  • contextmenu – происходит, когда кликнули на элемент правой кнопкой мыши.
  • mouseover / mouseout – когда мышь наводится на / покидает элемент.
  • mousedown / mouseup – когда нажали / отжали кнопку мыши на элементе.
  • mousemove – при движении мыши.

События на элементах управления:

  • submit – пользователь отправил форму .
  • focus – пользователь фокусируется на элементе, например нажимает на .

Клавиатурные события:

  • keydown и keyup – когда пользователь нажимает / отпускает клавишу.

События документа:

  • DOMContentLoaded – когда HTML загружен и обработан, DOM документа полностью построен и доступен.

CSS events:

  • transitionend – когда CSS-анимация завершена.

Существует множество других событий. Мы подробно разберём их в последующих главах.

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

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

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

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

Использование атрибута HTML

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

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

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

Обратите внимание, для содержимого атрибута onclick используются одинарные кавычки, так как сам атрибут находится в двойных. Если мы забудем об этом и поставим двойные кавычки внутри атрибута, вот так: onclick=»alert(«Click!»)» , код не будет работать.

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

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

  

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

Использование свойства DOM-объекта

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

К примеру, elem.onclick :

   

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

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

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

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

   

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

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

   

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

function sayThanks() < alert('Спасибо!'); >elem.onclick = sayThanks;

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

Доступ к элементу через this

Внутри обработчика события this ссылается на текущий элемент, то есть на тот, на котором, как говорят, «висит» (т.е. назначен) обработчик.

В коде ниже button выводит своё содержимое, используя this.innerHTML :

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

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

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

// правильно button.onclick = sayThanks; // неправильно button.onclick = sayThanks();

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

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

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

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

button.onclick = function() < sayThanks(); // содержимое атрибута >;

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

Назначение обработчика строкой elem.onclick = «alert(1)» также сработает. Это сделано из соображений совместимости, но делать так не рекомендуется.

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

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

// при нажатии на body будут ошибки, // атрибуты всегда строки, и функция станет строкой document.body.setAttribute('onclick', function() < alert(1) >);

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

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

addEventListener

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

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

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

input.onclick = function() < alert(1); >// . input.onclick = function() < alert(2); >// заменит предыдущий обработчик

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

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

element.addEventListener(event, handler, [options]);
  • once : если true , тогда обработчик будет автоматически удалён после выполнения.
  • capture : фаза, на которой должен сработать обработчик, подробнее об этом будет рассказано в главе Всплытие и погружение. Так исторически сложилось, что options может быть false/true , это то же самое, что .
  • passive : если true , то указывает, что обработчик никогда не вызовет preventDefault() , подробнее об этом будет рассказано в главе Действия браузера по умолчанию.

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

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

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

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

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

elem.addEventListener( "click" , () => alert('Спасибо!')); // . elem.removeEventListener( "click", () => alert('Спасибо!'));

Обработчик не будет удалён, т.к. в removeEventListener передана не та же функция, а другая, с одинаковым кодом, но это не важно.

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

function handler() < alert( 'Спасибо!' ); >input.addEventListener("click", handler); // . input.removeEventListener("click", handler);

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

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

   

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

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

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

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

document.onDOMContentLoaded = function() < alert("DOM построен"); // не будет работать >;
document.addEventListener("DOMContentLoaded", function() < alert("DOM построен"); // а вот так сработает >);

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

Объект события

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

Когда происходит событие, браузер создаёт объект события, записывает в него детали и передаёт его в качестве аргумента функции-обработчику.

Пример ниже демонстрирует получение координат мыши из объекта события:

Некоторые свойства объекта event :

event.type Тип события, в данном случае «click» . event.currentTarget Элемент, на котором сработал обработчик. Значение – обычно такое же, как и у this , но если обработчик является функцией-стрелкой или при помощи bind привязан другой объект в качестве this , то мы можем получить элемент из event.currentTarget . event.clientX / event.clientY Координаты курсора в момент клика относительно окна, для событий мыши.

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

Объект события доступен и в HTML

При назначении обработчика в HTML, тоже можно использовать объект event , вот так:

Это возможно потому, что когда браузер из атрибута создаёт функцию-обработчик, то она выглядит так: function(event) < alert(event.type) >. То есть, её первый аргумент называется «event» , а тело взято из атрибута.

Объект-обработчик: handleEvent

Мы можем назначить обработчиком не только функцию, но и объект при помощи addEventListener . В этом случае, когда происходит событие, вызывается метод объекта handleEvent .

 

Как видим, если addEventListener получает объект в качестве обработчика, он вызывает object.handleEvent(event) , когда происходит событие.

Мы также можем использовать класс для этого:

 

Здесь один и тот же объект обрабатывает оба события. Обратите внимание, мы должны явно назначить оба обработчика через addEventListener . Тогда объект menu будет получать события mousedown и mouseup , но не другие (не назначенные) типы событий.

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

 

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

Итого

Есть три способа назначения обработчиков событий:

  1. Атрибут HTML: onclick=». » .
  2. DOM-свойство: elem.onclick = function .
  3. Специальные методы: elem.addEventListener(event, handler[, phase]) для добавления, removeEventListener для удаления.

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

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

Последний способ самый гибкий, однако нужно писать больше всего кода. Есть несколько типов событий, которые работают только через него, например, DOMContentLoaded . Также addEventListener поддерживает объекты в качестве обработчиков событий. В этом случае вызывается метод объекта handleEvent .

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

Мы изучим больше о событиях и их типах в следующих главах.

Объект события Event

Объект Event описывает событие, произошедшее на странице. Одной из причин возникновения событий являются действия пользователя, такие как клики мышкой Mouse Event или ввод с клавиатуры Keyboard Event . Существует множество различных событий с разным набором информации.

Обратите внимание на обзорную статью о событиях. В ней описываются примеры работы с событиями.

Пример

Скопировать ссылку «Пример» Скопировано

Самый простой и широко распространённый способ использования событий — это отслеживание срабатывания кликов по каким-либо элементам на странице.

При подписке на событие мы передаём обработчик, который будет вызван при каждом срабатывании события в браузере. В случае, когда происходит событие типа click , обработчик будет вызван с событием Mouse Event :

 element.addEventListener('click', function (event)  console.log(event)>) element.addEventListener('click', function (event)  console.log(event) >)      

Как пишется

Скопировать ссылку «Как пишется» Скопировано

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

Свойства

Скопировать ссылку «Свойства» Скопировано

  • bubbles — является ли данное событие всплывающим.
  • cancelable — является ли событие отменяемым.
  • current Target — указывает на элемент, на котором установлен обработчик события.
  • default Prevented — отменено ли поведение события по умолчанию.
  • event Phase — указывает на фазу срабатывания события.
  • is Trusted — указывает на происхождение события, будет в значении true , если событие инициировано действиями пользователя. false — если событие инициировано из кода с помощью dispatch Event ( ) .
  • target — ссылка на объект, которым было инициировано событие. Например, если событие произошло на поле ввода, мы получим ссылку на этот DOM элемент.
  • time Stamp — время возникновения события в миллисекундах.
  • type — тип события.

Методы

Скопировать ссылку «Методы» Скопировано

  • composed Path ( ) — вернёт массив элементов, на которых сработает событие.
  • prevent Default ( ) — предотвращает дефолтное поведение события. Если вызвать этот метод на событии клика по ссылке, то переход по ссылке не произойдёт, но событие продолжит всплытие.
  • stop Propagation ( ) — предотвращает всплытие события.
  • stop Immediate Propagation ( ) — делает то же самое, что и stop Propagation , но в том числе предотвращает вызов обработчиков события, которые были установлены на этом же элементе.

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

Как понять

Скопировать ссылку «Как понять» Скопировано

Работа JavaScript основана на событийной модели — это значит, что для того, чтобы запустить какой-либо код, должно произойти событие. Даже код, который был написан в файле и не привязан к какому-либо событию, будет обработан после того, как произойдёт событие, которое сообщит браузеру, что код был загружен.

Событие может быть создано по следующим причинам:

  • действие пользователя;
  • системное событие;
  • событие, созданное программно.

Примеры

Скопировать ссылку «Примеры» Скопировано

Системное событие

Скопировать ссылку «Системное событие» Скопировано

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

Мы можем отслеживать состояние интернет-соединения и показывать сообщение, если оно пропало.

 window.addEventListener('offline', function()  alert('Отсутствует подключение к интернету')>) window.addEventListener('offline', function()  alert('Отсутствует подключение к интернету') >)      
Программное событие

Скопировать ссылку «Программное событие» Скопировано

Событие может быть создано с помощью кода, поле is Trusted в таком событии будет содержать значение false , а значит, мы будем знать, что событие было вызвано не системно и не пользователем.

Создадим своё событие и вызовем его на window :

 const myEvent = new CustomEvent('my-event',  detail:  spicy: 123, >,>) window.addEventListener('my-event', function(evt)  console.log('В поле spicy:', evt.detail.spicy)>) window.dispatchEvent(myEvent) const myEvent = new CustomEvent('my-event',  detail:  spicy: 123, >, >) window.addEventListener('my-event', function(evt)  console.log('В поле spicy:', evt.detail.spicy) >) window.dispatchEvent(myEvent)      

На практике

Скопировать ссылку «На практике» Скопировано

Павел Минеев советует

Скопировать ссылку «Павел Минеев советует» Скопировано

�� В событии есть два похожих поля: target и current Target . Их отличие легко увидеть на примере.

   Моя кнопочка  button class="button" type="button"> span>Моя кнопочкаspan> button>      
 document.querySelector('.button').addEventListener('click', function (event)  console.log('Событие инициировано на', event.target) console.log('Событие поймано на', event.currentTarget)>) document.querySelector('.button').addEventListener('click', function (event)  console.log('Событие инициировано на', event.target) console.log('Событие поймано на', event.currentTarget) >)      

current Target всегда будет элементом, к которому привязан обработчик, то есть элементом, на котором вызывался add Event Listener ( ) .

target — это элемент, на котором произошло событие. Оно может не совпадать с current Target , потому что большинство событий всплывают.

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

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

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

— это строка, определяющая тип действия, вызвавшего событие. Тип «mousemove», например, означает, что пользователь переместил указатель мыши. Тип «keydown» означает, что была нажата клавиша на клавиатуре. А тип «load» означает, что завершилась загрузка документа (или какого-то другого ресурса) из сети. Поскольку тип события — это просто строка, его иногда называют именем события.

— это объект, в котором возникло событие или с которым это событие связано. Когда говорят о событии, обычно упоминают тип и цель события. Например, событие «load» объекта Window или событие «click» элемента . Самыми типичными целями событий в клиентских приложениях на языке JavaScript являются объекты Window, Document и Element, но некоторые типы событий могут происходить и в других типах объектов.

— это функция, которая обрабатывает, или откликается на событие. Приложения должны зарегистрировать свои функции обработчиков событий в веб-браузере, указав тип события и цель. Когда в указанном целевом объекте возникнет событие указанного типа, браузер вызовет обработчик. Когда обработчики событий вызываются для какого-то объекта, мы иногда говорим, что браузер «возбудил» или «сгенерировал» событие.

— это объект, связанный с определенным событием и содержащий информацию об этом событии. Объекты событий передаются функции обработчика события в виде аргумента (кроме IE8 и более ранних версий, где объект события доступен только в виде глобальной переменной event). Все объекты событий имеют свойство type, определяющее тип события, и свойство target, определяющее цель события.

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

— это процесс, в ходе которого браузер решает, в каких объектах следует вызвать обработчики событий. В случае событий, предназначенных для единственного объекта (таких как событие «load» объекта Window), надобность в их распространении отсутствует. Однако, когда некоторое событие возникает в элементе документа, оно распространяется, или «всплывает», вверх по дереву документа.

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

Регистрация обработчиков событий

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

Дело осложняется тем, что каждый прием имеет две версии. Свойство обработчика события можно установить в программном коде на языке JavaScript или в элементе документа, определив соответствующий атрибут непосредственно в разметке HTML. Регистрация обработчиков вызовом метода может быть выполнена стандартным методом с именем addEventListener(), который поддерживается всеми браузерами, кроме IE версии 8 и ниже, и другим методом, с именем attachEvent(), поддерживаемым всеми версиями IE до IE9.

Установка свойств обработчиков событий

Самый простой способ зарегистрировать обработчик события заключается в том, чтобы присвоить свойству целевого объекта события желаемую функцию обработчика. По соглашению свойства обработчиков событий имеют имена, состоящие из слова «on», за которым следует имя события: onclick, onchange, onload, onmouseover и т.д. Обратите внимание, что эти имена свойств чувствительны к регистру и в них используются только строчные символы, даже когда имя типа события состоит из нескольких слов (например «readystatechange»). Ниже приводятся два примера регистрации обработчиков событий:

// Присвоить функцию свойству onload объекта Window. // Функция - обработчик события: она вызывается, когда документ будет загружен window.onload = function() < // Отыскать элемент var elt = document.getElementById("shipping_address"); // Зарегистрировать обработчик события, который будет вызываться // непосредственно перед отправкой формы elt.onsubmit = function() < return validate(this); >> 

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

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

Установка атрибутов обработчиков событий

Свойства обработчиков событий в элементах документа можно также устанавливать, определяя значения атрибутов в соответствующих HTML-тегах. В этом случае значение атрибута должно быть строкой программного кода на языке JavaScript. Этот программный код должен быть не полным объявлением функции обработчика события, а только ее телом. То есть реализация обработчика события в разметке HTML не должна заключаться в фигурные скобки и предваряться ключевым словом function. Например:

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

Некоторые типы событий предназначены для браузера в целом, а не для какого-то конкретного элемента документа. Обработчики таких событий в языке JavaScript регистрируются в объекте Window. В разметке HTML они должны помещаться в тег , но браузер зарегистрирует их в объекте Window. Ниже приводится полный список таких обработчиков событий, определяемых проектом спецификации HTML5:

onafterprint onfocus ononline onresize onbeforeprint onhashchange onpagehide onstorage onbeforeunload onload onpageshow onundo onblur onmessage onpopstate onunload onerror onoffline onredo

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

addEventListener()

В стандартной модели событий, поддерживаемой всеми браузерами, кроме IE версии 8 и ниже, целью события может быть любой объект — включая объекты Window и Document и все объекты Elements элементов документа — определяющий метод с именем addEventListener(), с помощью которого можно регистрировать обработчики событий для этой цели.

Метод addEventListener() принимает три аргумента. Первый — тип события, для которого регистрируется обработчик. Тип (или имя) события должен быть строкой и не должен включать префикс «on», используемый при установке свойств обработчиков событий. Вторым аргументом методу addEventListener() передается функция, которая должна вызываться при возникновении события указанного типа. В последнем аргументе методу addEventListener() передается логическое значение. Обычно в этом аргументе передается значение false. Если передать в нем значение true, функция будет зарегистрирована как перехватывающий обработчик и будет вызываться в другой фазе распространения события.

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

Следующий фрагмент регистрирует два обработчика события «click» в элементе . Обратите внимание на различия двух используемых приемов:

  

Вызов метода addEventListener() со строкой «click» в первом аргументе никак не влияет на значение свойства onclick. Во фрагменте, приведенном выше, щелчок на кнопке приведет к выводу двух диалоговых окон alert(). Но важнее то, что метод addEventListener() можно вызвать несколько раз и зарегистрировать с его помощью несколько функций-обработчиков для одного и того же типа события в том же самом объекте. При появлении события в объекте будут вызваны все обработчики, зарегистрированные для этого типа события, в порядке их регистрации.

Многократный вызов метода addEventListener() для одного и того же объекта с теми же самыми аргументами не дает никакого эффекта — функция-обработчик регистрируется только один раз и повторные вызовы не влияют на порядок вызова обработчиков.

Парным к методу addEventListener() является метод removeEventListener(), который принимает те же три аргумента, но не добавляет, а удаляет функцию-обработчик из объекта. Это часто бывает удобно, когда необходимо зарегистрировать временный обработчик события, а затем удалить его в какой-то момент.

Internet Explorer версии ниже IE9 не поддерживает методы addEventListener() и removeEventListener(). В версии IE5 и выше определены похожие методы, attachEvent() и detachEvent(). Поскольку модель событий в IE не поддерживает фазу перехвата, методы attachEvent() и detachEvent() принимают только два аргумента: тип события и функцию обработчика, при этом в первом аргументе методам в IE передается имя свойства обработчика с префиксом «on», а не тип события без этого префикса.

Вызов обработчиков событий

После регистрации обработчика событий веб-браузер будет вызывать его автоматически, когда в указанном объекте будет возникать событие указанного типа. В этом разделе подробно описывается порядок вызова обработчиков событий, аргументы обработчиков, контекст вызова (значение this) и назначение возвращаемого значения обработчика. К сожалению, некоторые из этих подробностей отличаются между IE версии 8 и ниже и другими браузерами.

Аргумент обработчика событий

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

В IE версии 8 и ниже обработчикам событий, зарегистрированным установкой свойства, объект события при вызове не передается. Вместо этого объект события сохраняется в глобальной переменной window.event. Для переносимости обработчики событий можно оформлять, как показано ниже, чтобы они использовали переменную window.event при вызове без аргумента:

function handler(event) < event = event || window.event; // Здесь находится реализация обработчика >

Объект события передается обработчикам событий, зарегистрированным с помощью метода attachEvent(), но они также могут использовать переменную window.event.

При регистрации обработчика события посредством HTML-атрибута браузер преобразует строку с программным кодом на языке JavaScript в функцию. Браузеры, отличные от IE, создают функцию с единственным аргументом event. В IE создается функция, не принимающая аргументов. Если в таких функциях использовать идентификатор event, он будет ссылаться на window.event. В любом случае обработчики событий, определяемые в разметке HTML, могут ссылаться на объект события, используя идентификатор event.

Контекст обработчиков событий

Когда обработчик событий регистрируется установкой свойства, это выглядит как определение нового метода элемента документа:

e.onclick = function() < /* реализация обработчика */ >;

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

В обработчиках ключевое слово this ссылается на целевой объект, даже когда они были зарегистрированы с помощью метода addEventListener(). Однако, к сожалению, это не относится к методу attachEvent(): обработчики, зарегистрированные с помощью метода attachEvent(), вызываются как функции, и в них ключевое слово this ссылается на глобальный (Window) объект. Эту проблему можно решить следующим способом:

/* Регистрирует указанную функцию как обработчик событий указанного типа в указанном объекте. Гарантирует, что обработчик всегда будет вызываться как метод целевого объекта. */ function addEvent(target, type, handler) < if (target.addEventListener) target.addEventListener(type, handler, false); else target.attachEvent("on" + type, function(event) < // Вызвать обработчик как метод цели, // и передать ему объект события return handler.call(target, event); >); >

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

Возвращаемые значения обработчиков

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

Например, обработчик onclick кнопки отправки формы может вернуть false, чтобы предотвратить отправку формы браузером. (Это может пригодиться, если ввод пользователя не прошел проверку на стороне клиента.) Аналогично обработчик события onkeypress поля ввода может фильтровать ввод с клавиатуры, возвращая false при вводе недопустимых символов.

Также важно значение, возвращаемое обработчиком onbeforeunload объекта Window. Это событие генерируется, когда браузер выполняет переход на другую страницу. Если этот обработчик вернет строку, она будет выведена в модальном диалоговом окне, предлагающем пользователю подтвердить свое желание покинуть страницу.

Важно понимать, что учитываются значения, возвращаемые обработчиками событий, только если обработчики зарегистрированы посредством установки свойств. Обработчики, зарегистрированные с помощью addEventListener() или attachEvent() вместо этого должны вызывать метод preventDefault() или устанавливать свойство returnValue объекта события.

Отмена событий

Значение, возвращаемое обработчиком события, зарегистрированным как свойство, можно использовать для отмены действий, выполняемых браузером по умолчанию в случае этого события. В браузерах, поддерживающих метод addEventListener(), отменить выполнение действий по умолчанию можно также вызовом метода preventDefault() объекта события. Однако в IE, версии 8 и ниже, тот же эффект достигается установкой свойства returnValue объекта события в значение false.

В следующем фрагменте демонстрируется обработчик события клика по гиперссылке, который использует все три способа отмены события (блокирует переход пользователя по ссылке):

window.onload = function() < // Найти все ссылки var a_href = document.getElementsByTagName('a'); // Добавить обработчик события click (не для IE<=8) for(var i = 0; i < a_href.length; i++) a_href[i].addEventListener('click', function(e) , false); >;

Текущий проект модуля «DOM Events 3» определяет в объекте Event свойство с именем defaultPrevented. Оно пока поддерживается не всеми браузерами, но суть его в том, что при обычных условиях оно имеет значение false и принимает значение true только в случае вызова метода preventDefault().

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

В IE версии 8 и ниже метод stopPropagation() не поддерживается. Вместо этого объект события в IE имеет свойство cancelBubble. Установка этого свойства в значение true предотвращает распространение события.

Текущий проект спецификации «DOM Events 3» определяет в объекте Event еще один метод — метод с именем stopImmediatePropagation(). Подобно методу stopPropagation(), он предотвращает распространение события по любым другим объектам. Но кроме того, он также предотвращает вызов любых других обработчиков событий, зарегистрированных в том же объекте.

Событийная модель

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

Время чтения: 7 мин

Открыть/закрыть навигацию по статье

  1. Кратко
  2. Как пишется
    1. on-свойства DOM-элементов
    2. Метод addEventListener()
    1. Функция-обработчик
    2. Всплытие событий
    1. Николай Лопин советует

    Контрибьюторы:

    • Егор Левченко ,
    • Светлана Коробцева

    Обновлено 14 октября 2022

    Кратко

    Скопировать ссылку «Кратко» Скопировано

    Чтобы приложение было интерактивным, нам нужно понимать, что пользователь совершил то или иное действие на странице. Браузер распознает действия пользователя и создаёт событие.

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

    События бывают разных типов: клик, нажатие клавиши на клавиатуре, прокрутка страницы и так далее.

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

    Как пишется

    Скопировать ссылку «Как пишется» Скопировано

    Существует два способа обработать события:

    • с помощью on -свойств DOM-элементов;
    • методом add Event Listener ( ) .

    on -свойства DOM-элементов

    Скопировать ссылку «on-свойства DOM-элементов» Скопировано

    Большинство событий связаны с DOM-элементами. Если пользователь кликнул на кнопку, то событие click связано с конкретным DOM-элементом — кнопкой, на которой кликнул пользователь.

    Каждый DOM-элемент имеет большой набор свойств, которые начинаются на on :

    • onclick ;
    • onscroll ;
    • onkeypress ;
    • onmouseenter ;
    • и так далее.

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

     const buttonElement = document.getElementById('change')const squareDiv = document.getElementById('square') // чтобы реагировать на нажатие кнопки, записываем функцию в свойство onclick.// Эта функция будет вызываться при каждом нажатии на кнопку. Часто говорят,// что эта функция обрабатывает событиеbuttonElement.onclick = function()  squareDiv.style = `background-color: $;`> function getColor()  const colors = [ '#49A16C', '#064236', '#ED6742', '#F498AD', '#1A5AD7', '#AFC9DA', '#FFD829', '#282A2E', '#5E6064', '#E6E6E6' ] return colors[Math.floor(Math.random() * colors.length)]> const buttonElement = document.getElementById('change') const squareDiv = document.getElementById('square') // чтобы реагировать на нажатие кнопки, записываем функцию в свойство onclick. // Эта функция будет вызываться при каждом нажатии на кнопку. Часто говорят, // что эта функция обрабатывает событие buttonElement.onclick = function()  squareDiv.style = `background-color: $getColor()>;` > function getColor()  const colors = [ '#49A16C', '#064236', '#ED6742', '#F498AD', '#1A5AD7', '#AFC9DA', '#FFD829', '#282A2E', '#5E6064', '#E6E6E6' ] return colors[Math.floor(Math.random() * colors.length)] >      

    Чтобы перестать обрабатывать событие, нужно записать в свойство значение null .

    Метод add Event Listener ( )

    Скопировать ссылку «Метод addEventListener()» Скопировано

    �� Если обрабатывать события с помощью on -свойств, то получится добавить только одну функцию-обработчик на каждый элемент. Часто одного обработчика недостаточно. Чтобы не создавать ограничение на пустом месте, используют альтернативный метод подписки на события — метод add Event Listener ( ) .

    Метод вызывается у DOM-элемента. Аргументами нужно передать тип события (справочная информация) и функцию, которую нужно выполнить:

     const buttonElement = document.getElementById('change')const squareDiv = document.getElementById('square') // чтобы реагировать на нажатие кнопки, подписываемся на событие click и передаем// функцию-обработчик. Эта функция будет вызываться при каждом нажатии на кнопкуbuttonElement.addEventListener('click', function()  squareDiv.style = `background-color: $;`>) const buttonElement = document.getElementById('change') const squareDiv = document.getElementById('square') // чтобы реагировать на нажатие кнопки, подписываемся на событие click и передаем // функцию-обработчик. Эта функция будет вызываться при каждом нажатии на кнопку buttonElement.addEventListener('click', function()  squareDiv.style = `background-color: $getColor()>;` >)      

    Как понять

    Скопировать ссылку «Как понять» Скопировано

    Функция-обработчик

    Скопировать ссылку «Функция-обработчик» Скопировано

    Функция-обработчик, или просто обработчик, — это функция, которая вызывается браузером при наступлении события.

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

    Объект события — это JavaScript-объект с информацией о событии. В объекте события есть как общие свойства (тип события, время события), так и свойства, которые зависят от типа события (например, на какую кнопку нажал пользователь).

    Чтобы работать с объектом события, нужно добавить параметр в объявление обработчика. Обработаем нажатие на кнопки клавиатуры и получим из объекта события информацию о нажатой кнопке:

     window.addEventListener('keydown', function (event)  // используем объект события, чтобы получить информацию о нажатой клавише alert(`Вы нажали на кнопку: $`)>) window.addEventListener('keydown', function (event)  // используем объект события, чтобы получить информацию о нажатой клавише alert(`Вы нажали на кнопку: $event.key>`) >)      

    Помимо объекта события, внутри функции можно использовать ключевое слово this . Оно позволяет получить DOM-элемент, на котором сработал обработчик. Это позволяет создать обработчик один раз, но привязать её к нескольким DOM-элементам.

    Например, мы объявим обработчик в виде именованной функции и повесим её на нажатие нескольких кнопок. При клике на кнопку будем менять её цвет:

     function changeColor()  // меняем цвет кнопки, на которой произошло событие. кнопка доступна с помощью // ключевого слова this this.style = `background-color: $;`;>; const buttons = document.getElementsByTagName('button');for (let i = 0; i < buttons.length; ++i)  const button = buttons[i]; // к каждой кнопке привязываем обработчик button.addEventListener('click', changeColor); // обратите внимание, что мы не вызываем // функцию changeColor, а только пишем ее имя> function changeColor()  // меняем цвет кнопки, на которой произошло событие. кнопка доступна с помощью // ключевого слова this this.style = `background-color: $getColor()>;`; >; const buttons = document.getElementsByTagName('button'); for (let i = 0; i  buttons.length; ++i)  const button = buttons[i]; // к каждой кнопке привязываем обработчик button.addEventListener('click', changeColor); // обратите внимание, что мы не вызываем // функцию changeColor, а только пишем ее имя >      

    Всплытие событий

    Скопировать ссылку «Всплытие событий» Скопировано

     const container = document.getElementById('container')const video = document.getElementById('cat') // обрабатываем событие click на container.addEventListener('click', function()  const colors = ['#49A16C', '#064236', '#ED6742', '#F498AD', '#1A5AD7', '#AFC9DA', '#FFD829', '#282A2E', '#5E6064'] const randomColorIndex = Math.floor(Math.random() * colors.length) container.style = `background-color: $`>); // обрабатываем событие click на видеоvideo.addEventListener('click', function()  this.currentTime = 0 // отматываем видео на начало this.play()>) const container = document.getElementById('container') const video = document.getElementById('cat') // обрабатываем событие click на container.addEventListener('click', function()  const colors = ['#49A16C', '#064236', '#ED6742', '#F498AD', '#1A5AD7', '#AFC9DA', '#FFD829', '#282A2E', '#5E6064'] const randomColorIndex = Math.floor(Math.random() * colors.length) container.style = `background-color: $colors[randomColorIndex]>` >); // обрабатываем событие click на видео video.addEventListener('click', function()  this.currentTime = 0 // отматываем видео на начало this.play() >)      

    �� Обратите внимание, что событие срабатывает на обоих элементах — цвет фона меняется и запускается видео. Этому есть объяснение, оно называется всплытие событий (event bubbling).

    Когда пользователь совершает действие, браузер ищет самый вложенный элемент, к которому относится событие. Затем это событие передаётся родительскому элементу и так далее до самого корня DOM.

    В нашем примере мы кликнули на , это самый вложенный элемент. Браузер создал событие, и мы обработали его в коде. После этого браузер передаёт событие родителю (то есть элементу, который содержит ) — элементу . Мы получаем его и обрабатываем. И он всплывает дальше, пока не дойдёт до .

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

    Если кликнуть по блокам на демо, то можно увидеть, как событие всплывает вверх к родителям:

     let activelet counter = 0 // обрабатываем событие click на всех let divs = Array.from(document.querySelectorAll('div')).reverse()for (let i = 0; i < divs.length; ++i)  const isLast = (i + 1 === divs.length) divs[i].addEventListener('click', clickHandlerGenerator(isLast))> function clickHandlerGenerator(isLast = false)  return function()  let me = this setTimeout(function()  if (active)  active.classList.remove('active') > me.classList.add('active') active = me if (isLast)  setTimeout(function()  active.classList.remove('active') active = undefined counter = 0 >, 300) > >, counter * 300) ++counter >> let active let counter = 0 // обрабатываем событие click на всех let divs = Array.from(document.querySelectorAll('div')).reverse() for (let i = 0; i  divs.length; ++i)  const isLast = (i + 1 === divs.length) divs[i].addEventListener('click', clickHandlerGenerator(isLast)) > function clickHandlerGenerator(isLast = false)  return function()  let me = this setTimeout(function()  if (active)  active.classList.remove('active') > me.classList.add('active') active = me if (isLast)  setTimeout(function()  active.classList.remove('active') active = undefined counter = 0 >, 300) > >, counter * 300) ++counter > >      

    Всплытие события можно остановить с помощью метода stop Propagation ( ) у объекта события:

     video.addEventListener('click', function (event)  event.stopPropagation() this.currentTime = 0 this.play()>) video.addEventListener('click', function (event)  event.stopPropagation() this.currentTime = 0 this.play() >)      

    На практике

    Скопировать ссылку «На практике» Скопировано

    Николай Лопин советует

    Скопировать ссылку «Николай Лопин советует» Скопировано

    �� Всегда подписывайтесь на события с помощью add Event Listener ( ) , так вы избежите доработок, когда потребуется повесить несколько обработчиков на одно и то же событие.

    �� Если нужно обработать все события определённого типа, вызовите метод add Event Listener ( ) у объекта window :

     // обрабатываем все клики на страницеwindow.addEventListener('click', function ()  alert('clicked')>) // обрабатываем все клики на странице window.addEventListener('click', function ()  alert('clicked') >)      

    �� Если вы не используете объект события в обработчике, то можно не указывать его в списке параметров обработчика. Вместо function ( event ) пишите function ( ) .

    �� Всплытие событий — важный концепт, поэкспериментируйте с ним, чтобы лучше в нём разобраться.

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

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