События в JavaScript
Для реакции на действия посетителя и внутреннего взаимодействия скриптов существуют события.
Событие – это сигнал от браузера о том, что что-то произошло. Существует много видов событий.
Самым ярким примером события это нажатие пользователя по какому-то объекту(click
), будь то это кнопка, ссылка или любой другой элемент. Другой пример события, это наведение мыши над каким-то объектом(mouseover
), скажем над изображением. Также событием является полное загрузка страницы(load
). В общем все действия, которые происходят на сайте являются событиями.
Обработчик событий
Для того чтобы обрабатывать какое-то событие, необходимо использовать специальный обработчик для данного события.
Обработчик события - это функция, которая обрабатывает, или откликается на событие, как только оно произошло. Когда в объекте возникнет событие указанного типа, браузер вызовет незамедлительно обработчик.
Именно благодаря обработчикам JavaScript-код может реагировать на действия посетителя.
Есть несколько способов назначить событию обработчик.
HTML
атрибуты событий
Обработчик может быть назначен прямо в разметке, в атрибуте, который имеет вид on<событие>
.
HTML атрибуты событий - это специальные глобальные атрибуты, используемые в тегах для вызова обработчиков событий, написанных на различных языках сценариев и вызываемых, когда на странице происходит какое-либо действие.
<button onclick="alert('Hello? user zamt')">Нажми меня</button>
В значение обработчика можно написать сразу код JavaScript, но лучше вызывать какую-то функцию, которая сделает необходимые действия. Функцию необходимо описать внутри тега <script>
, который может находится как внутри блока <head>
, так и в конце тега <body>
.
Атрибуты событий окна(window
)
События, вызываемые на объект окна(window
). Данные события применяются с тегом <body>
.
Атрибут | Описание |
---|---|
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
:
type
- строка, содержащее имя событияtarget
- DOM-элемент, который сгенерировал событиеcurrentTarget
- DOM-элемент, который вызвал обработчик событияeventPhase
- число, показывающее на каком этапе произошло событие (1 - этапе погружения (перехвата), 2 - на цели, 3 - на этапе всплытия)timestamp
- число (дата), когда произошло событиеbubbles
- возвращает логическое значение, указывающее может ли данное событие всплыватьview
- возвращает ссылку на объектwindow
, в котором произошло событие
Свойства объекта event
, предназначенные для получения дополнительной информации о событиях, связанных с клавиатурой и мышью
Ниже представлены не все свойтва, а лишь некоторые из них
which
- (для мыши)возвращает число, указывающее, какая кнопка мыши была нажата (1 - левая кнопка, 2 - средняя кнопка, 3 - правая кнопка). Это свойство в основном используется вместе с событиемmousedown
. Данное свойство может использоваться для получения дополнительной информации о событие, связанном с нажатием кнопки мыши.clientX, clientY
- (для мыши)возвращают информацию о положении курсора (clientX
- горизонтальная координата,clientY
- вертикальная координата) относительно левого верхнего угла клиентской областиscreenX, screenY
- (для мыши)возвращают информацию о положении курсора (screenX
- горизонтальная координата,screenY
- вертикальная координата) относительно левого верхнего угла экранаdetail
- (для мыши)возвращает число, указывающее сколько раз была нажата кнопка мыши в некоторой области за короткий промежуток времениaltKey, ctrlKey, metaKey, shiftKey
- (для мыши и клавиатуры)получение дополнительной информации о том была ли нажата соответствующая клавишаalt
,ctrl
иshift
в тот момент когда произошло событиеcharCode
- (для клавиатуры)возвращает код символа Unicode нажатой клавиши (для события keypress). Если данное свойство использовать для получения дополнительной информации о событияхkeydown
илиkeyup
, то оно всегда вернёт "0"keyCode, which
- (для клавиатуры)возвращает код символа Unicode (для событияkeypress
) или код ключа Unicode (для событийkeydown
иkeyup
)
Всплытие и перехват
Примечательно, что на одно событие может реагировать не только тот элемент, на котором произошло событие, но и элементы над ним.
Это очень удобно, например если в элементе содержатся много дочерних HTML-тегов - не обязательно ставить обработчик на каждый, достаточно указать один обработчик на родителе и в нем ловить все события.
Рассмотрим ситуацию, когда у вас есть элементы "вложенные" друг в друга.
При наступлении события обработчики сначала срабатывают на самом вложенном элементе, затем на его родителе, затем выше и так далее, вверх по цепочке вложенности.
Этот процесс называется всплытием, потому что события «всплывают» от внутреннего элемента вверх через родителей, подобно тому, как всплывает пузырек воздуха в воде.
Всплывают почти все события. Ключевое слово в этой фразе - «почти». Например, событие focus
не всплывает.
Целевой элемент event.target
На каком бы элементе мы ни поймали событие, всегда можно узнать, где конкретно оно произошло.
Самый глубокий элемент, который вызывает событие, называется «целевым» или «исходным» элементом и доступен как event.target
.
Отличия от this
(=event.currentTarget
)
event.target
- это исходный элемент, на котором произошло событие, в процессе всплытия он неизмененthis
- то текущий элемент, до которого дошло всплытие, на нём сейчас выполняется обработчик
Отмена всплытия
Нужно понимать, что всплытие происходит всегда. При возникновении события на элементе, сигнал будет подниматься до самого высокого элемента, выполняя нужные обработчики.
Если какой-то обработчик хочет остановить всплытие и не выпускать событие дальше вверх - это делается методом event.stopPropagation()
event.stopPropagation();
event.stopImmediatePropagation()
Если у элемента есть несколько обработчиков на одно событие, то даже при прекращении всплытия все они будут выполнены. То есть, event.stopPropagation()
препятствует продвижению события дальше, но на текущем элементе все обработчики отработают.
Для того, чтобы полностью остановить обработку, современные браузеры поддерживают метод event.stopImmediatePropagation()
. Он не только предотвращает всплытие, но и останавливает обработку событий на текущем элементе.
Перехват события
В современном стандарте, кроме «всплытия» событий, предусмотрено ещё и «погружение»(или по другому перехват). Перехват - это вторая, альтернативная всплытию модель порядка выполнения для события. Оно гораздо менее востребовано, но иногда, очень редко, знание о нём может быть полезным.
Когда в приложении возникает событие, оно не просто срабатывает один раз в месте своего происхождения; оно отправляется в путь, состоящий из трёх фаз. Первая фаза, событие движется от корня документа к цели (фаза перехвата), затем срабатывает для цели события (фаза цели) и движется назад к корню документа (фаза всплытия).
Замедленное воспроизведение продвижения события
Фаза перехвата так называется, потому что родительские элементы могут обработать событие раньше, чем непосредственная цель события, как бы "перехватывая" обработку.
Чтобы поймать событие на стадии перехвата, нужно использовать третий аргумент метода addEventListener()
//Если аргумент false, то событие будет поймано при всплытии element.addEventListener("click", funcClk, false); //Если аргумент true, то событие будет перехвачено по дороге вниз element.addEventListener("click", funcClk, true);
Если в качестве третьего параметра функции addEventListener()
передать значение true
, то событие будет срабатывать на фазе захвата, если false
– то после окончания захвата, на фазе всплытия.
Мы не будем рассматривать фазу захвата детально, так как в реальной жизни используется только всплытие.
Действия браузера по умолчанию
Для некоторых событий, которые происходят в документе, в браузере установлено поведение по умолчанию. Например, при нажатии на ссылку браузер осуществляет стандартное действие - это переход на страницу, указанную в атрибуте href
; при нажатии на кнопку <input type="submit">
в форме данные отправляются на сервер; движение колёсика мыши инициирующие прокрутку страницы; показывающиеся контекстное меню браузера при нажатии правой кнопки мыши и многие другие.
Иногда возникают ситуации, когда стандартные действия, которые выполняет браузер необходимо отменить.
И в ряде случаев реакцию браузера на событие мы можем убрать в обработчике, но некоторые поведения браузера по умолчанию отменить нельзя и об этом нужно помнить.
К примеру, в веб-приложениях обычно хотелось бы иметь возможность самостоятельно управлять навигацией, без перезагрузок страницы. Чтобы такую возможность получить, нужно предотвратить установленную по умолчанию реакцию браузера на клик, и вместо неё выполнить то, что задумали мы.
Отмена действия браузера
Существует два способа отмены действия браузера по умолчанию
- Основной способ для отмены стандартного действия - это метод
preventDefault()
объектаevent
- В случаи если обработчик назначен через
on<событие>
(не черезaddEventListener()
), то для отмены стандартного действия кромеevent.preventDefault()
также можно использоватьreturn false
Данный способ (return false
) не будет работать, если обработчик назначен через методaddEventListener()
.
Так же следует помнить, что отмена стандартного действия браузера не останавливает всплытие события.
В ситуациях, когда необходимо отменить стандартное действие браузера и всплытие события, можно использовать метод event.stopPropagation()
element.addEventListener("click", function(event) { event.preventDefault();//отмена стандартного действия браузера .... event.stopPropagation();//отмена всплытия события });