События в JavaScript

Для реакции на действия посетителя и внутреннего взаимодействия скриптов существуют события.

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

Самым ярким примером события это нажатие пользователя по какому-то объекту(click), будь то это кнопка, ссылка или любой другой элемент. Другой пример события, это наведение мыши над каким-то объектом(mouseover), скажем над изображением. Также событием является полное загрузка страницы(load). В общем все действия, которые происходят на сайте являются событиями.

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

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

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

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

Есть несколько способов назначить событию обработчик.

HTML атрибуты событий

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

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

<button onclick="alert('Hello? user zamt')">Нажми меня</button>    
			

В значение обработчика можно написать сразу код JavaScript, но лучше вызывать какую-то функцию, которая сделает необходимые действия. Функцию необходимо описать внутри тега <script>, который может находится как внутри блока <head>, так и в конце тега <body>.

Атрибуты событий окна(window)

События, вызываемые на объект окна(window). Данные события применяются с тегом <body>.

Атрибуты событий окна(window)
Атрибут Описание
onafterprint Скрипт запустится после того, как документ будет распечатан.
onbeforeprint Скрипт запустится прежде, чем документ будет распечатан.
onbeforeonload Скрипт запустится до загрузки документа.
onblur Скрипт запустится, когда окно потеряет фокус.
onerror Скрипт запустится, если произойдет ошибка.
onfocus Скрипт запустится, когда окно получит фокус.
onhaschange Скрипт запустится, после изменения документа.
onload Код события будет выполнен после полной загрузки страницы, т.е. когда всё содержимое веб-страницы полностью загружено, включая изображения, внешние таблицы стилей и внешние скрипты.
onmessage Скрипт запустится при срабатывании сообщения.
onoffline Скрипт запустится, когда документ перейдет в автономный режим.
ononline Скрипт запустится, когда документ войдет в сеть.
onpagehide Скрипт запустится, когда окно будет скрыто.
onpageshow Скрипт запустится, когда окно станет видимым.
onpopstate Скрипт запустится при изменении окна истории.
onredo Скрипт запустится, когда документ начнет выполнять повтор.
onresize Скрипт запустится при изменении размеров окна.
onstorage Скрипт запустится при загрузке документа.
onundo Скрипт запустится при выполнении команды отменить в документе.
onunload Скрипт запустится при выходе пользователя из документа.

События формы

События срабатывают на действия внутри HTML формы.

События формы
Атрибут Описание
onblur Скрипт запустится, когда элемент потеряет фокус.
onchange Скрипт запустится при изменении элемента.
oncontextmenu Скрипт запустится при вызове контекстного меню.
onfocus Скрипт запустится, когда элемент получит фокус.
onformchange Скрипт запустится при изменении формы.
onforminput Скрипт запустится, когда пользователь будет вводить данные в форму.
oninput Скрипт запустится, когда элемент станет получать пользовательский ввод.
oninvalid Скрипт запустится, когда элемент станет недействителен.
onselect Скрипт запустится при выборе элемента.
onsubmit Скрипт запустится при отправке формы.

События клавиатуры

События, вызываемые клавиатурой (могут применяться ко всем элементам HTML).

События клавиатуры
Атрибут Описание
onkeydown Скрипт запустится, когда будет нажата клавиша.
onkeypress Скрипт запустится после того, как клавиша была нажата и отпущена.
onkeyup Скрипт запустится при отпускании клавиши.

События мыши

События, вызываемые действиями мышкой(могут применяться ко всем элементам HTML).

События мыши
Атрибут Описание
onclick Код события будет выполнен по клику левой кнопкой мыши на элементе.
ondblclick Скрипт запустится после двойного клика мыши.
ondrag Скрипт запустится при перетаскивании элемента.
ondragend Скрипт запустится после операции перетаскивания.
ondragenter Скрипт запустится, когда элемент будет перенесен на допустимую зону падения.
ondragleave Скрипт запустится, когда элемент отпустят в действующий зоне падения.
ondragover Скрипт запустится, если элемент тащат за допустимую зону падения.
ondragstart Скрипт запустится в начале операции перетаскивания элемента.
ondrop Скрипт запустится после перетаскивания элемента при падении.
onmousedown Скрипт запустится при нажатии кнопки мыши.
onmousemove Скрипт запустится, когда указатель мыши начнет перемещаться.
onmouseout Скрипт запустится, когда указатель мыши будет перемещаться из элемента.
onmouseover Скрипт запустится, когда указатель мыши будет перемещаться над элементом.
onmouseup Скрипт запустится при отпускании кнопки мыши.
onmousewheel Скрипт запустится при использовании колеса мыши.
onscroll Скрипт запустится во время прокручивания полосы прокрутки элемента.

События медиа-файлов

События, вызываемые для медиа файлов, таких как видео, изображения и аудио (могут применяться ко всем элементам HTML, но чаще всего применяются к таким элементам, как <audio>, <embed>, <object> и <video>).

События медиа-файлов
Атрибут Описание
onabort Скрипт запустится при прерывании.
oncanplay Скрипт запустится, когда файл будет готов, чтобы начать проигрывание (когда будет достаточно буферизирован).
oncanplaythrough Скрипт запустится, когда файл может быть воспроизведен полностью (от начала до конца), не останавливаясь для буферизации.
ondurationchange Скрипт запустится при изменении длины продолжительности медиа файла.
onemptied Скрипт запустится, когда произошла какая-то неполадка и файл стал недоступен (например при разрыве связи с интернетом).
onended Скрипт запустится, когда аудио/видео файл дойдет до конца (например для вывода сообщения: спасибо за прослушивание/просмотр).
onerror Скрипт запустится, если возникнет ошибка при загрузке файла.
onloadeddata Скрипт запустится при загрузке данных медиа файла.
onloadedmetadata Скрипт запустится, когда загружены мета-данные (например размер и продолжительность).
onloadstart Скрипт запустится при загрузке файла прежде, чем начнет загружаться на самом деле.
onpause Скрипт запустится, если воспроизведение файла приостановлено (нажали паузу) пользователем или программно.
onplay Скрипт запустится, когда файл готов начать воспроизводиться.
onplaying Скрипт запустится при воспроизведении файла.
onprogress Скрипт запускается, когда браузер находится в процессе получения данных медиа файла.
onratechange Скрипт запускается, каждый раз, при изменении режима воспроизведения (например, когда пользователь переключается на медленное воспроизведение или режим быстрой перемотки).
onreadystatechange Скрипт запускается, каждый раз, при изменении состояния готовности (состояние готовности отслеживает состояние данных файла).
onseeked Скрипт запускается, когда атрибут seeked у тегов audio или video имеет значение "false", т.е.текущая позиция воспроизведения найдена.
onseeking Скрипт запускается, когда атрибут seeking у тегов audio или video имеет значение "true", т.е. текущая позиция воспроизведения перемещается.
onstalled Скрипт запускается, когда браузер не может получить данные медиа файла по любой причине.
onsuspend Скрипт запускается, когда получение данных медиа файла прекращается, до окончания полной загрузки по любой причине.
ontimeupdate Скрипт запускается, когда позиция воспроизведения изменилась (например, когда пользователь выбрал точку воспроизведения на много дальше от текущей).
onvolumechange Скрипт запускается каждый раз при изменении значения громкости звука (включая полное отключение звука).
onwaiting Скрипт запускается, когда медиа файл остановлен, но ожидается возобновление запуска (например, когда файл делает паузу для буферизации оставшихся данных).

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

Другой способ зарегистрировать обработчик события заключается в том, чтобы присвоить свойству DOM-элемента on<событие> желаемую функцию обработчика.

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

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

Обработчиком можно назначить так же и уже существующую функцию(см. пример выше), а если обработчик надо убрать – нужно назначить elem.onclick = null.

Оператор this

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

Оператор this возвращает ссылку на объект, являющийся текущим контекстом вызова. Это позволяет обращаться к свойствам "текущего" объекта: this.property.

Это можно использовать, чтобы получить свойства или изменить элемент

addEventListener() и removeEventListener()

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

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

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

addEventListener()

Метод может быть применём к любому существующему объекту в документе, включая объекты Window и Document

    element.addEventListener(event-name, callback[, use-capture]);
				

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

removeEventListener()

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

Для удаления нужно передать именно ту функцию-обработчик которая была назначена. Пример ниже не сработает
    element.addEventListener("click", fucntion() { alert("Hello");});
....
    element.removeEventListener("click", fucntion() { alert("Hello");});
				
В removeEventListener() передана не та же функция, а другая, с одинаковым кодом.

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

Чтобы хорошо обработать событие, недостаточно знать о том, что это – «клик» или «нажатие клавиши». Иногда могут понадобиться детали произошедшего. Детали произошедшего браузер записывает в объект события(event), который передаётся первым аргументом в обработчик.

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

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

    element.addEventListener("click", myEvent);

    fucntion myEvent(event) { 
        /* переменная event будет содержать объект event */ 
    }
	
    /* Или можно так */
	
    element.addEventListener("click", fucntion(event) {
        //переменная event будет содержать объект event
    });
			

Свойства и методы объекта event

Общие свойства объекта event:

Свойства объекта event, предназначенные для получения дополнительной информации о событиях, связанных с клавиатурой и мышью

Ниже представлены не все свойтва, а лишь некоторые из них

Всплытие и перехват

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

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

Рассмотрим ситуацию, когда у вас есть элементы "вложенные" друг в друга.

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

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

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

Всплывают почти все события. Ключевое слово в этой фразе - «почти». Например, событие focus не всплывает.

Целевой элемент event.target

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

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

Отличия от this (=event.currentTarget)

Отмена всплытия

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

Если какой-то обработчик хочет остановить всплытие и не выпускать событие дальше вверх - это делается методом event.stopPropagation()

    event.stopPropagation();
				

event.stopImmediatePropagation()

Если у элемента есть несколько обработчиков на одно событие, то даже при прекращении всплытия все они будут выполнены. То есть, event.stopPropagation() препятствует продвижению события дальше, но на текущем элементе все обработчики отработают.

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

Перехват события

В современном стандарте, кроме «всплытия» событий, предусмотрено ещё и «погружение»(или по другому перехват). Перехват - это вторая, альтернативная всплытию модель порядка выполнения для события. Оно гораздо менее востребовано, но иногда, очень редко, знание о нём может быть полезным.

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

Стандарт DOM Events 3

Порядок обработки в стандарте W3C

Замедленное воспроизведение продвижения события

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

Чтобы поймать событие на стадии перехвата, нужно использовать третий аргумент метода addEventListener()

    //Если аргумент false, то событие будет поймано при всплытии
    element.addEventListener("click", funcClk, false);
	
    //Если аргумент true, то событие будет перехвачено по дороге вниз
    element.addEventListener("click", funcClk, true);
				

Если в качестве третьего параметра функции addEventListener() передать значение true, то событие будет срабатывать на фазе захвата, если false – то после окончания захвата, на фазе всплытия.

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

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

Для некоторых событий, которые происходят в документе, в браузере установлено поведение по умолчанию. Например, при нажатии на ссылку браузер осуществляет стандартное действие - это переход на страницу, указанную в атрибуте href; при нажатии на кнопку <input type="submit"> в форме данные отправляются на сервер; движение колёсика мыши инициирующие прокрутку страницы; показывающиеся контекстное меню браузера при нажатии правой кнопки мыши и многие другие.

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

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

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

Отмена действия браузера

Существует два способа отмены действия браузера по умолчанию

Данный способ (return false) не будет работать, если обработчик назначен через метод addEventListener().

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

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

    element.addEventListener("click", function(event) {
        event.preventDefault();//отмена стандартного действия браузера
    ....
        event.stopPropagation();//отмена всплытия события
    });