Объект события
При возникновении какого-либо события на элементе страницы браузер автоматически создаёт объект, в котором содержится полезная информация о наступившем событии (например, свойство type
указывает тип события). Данный объект передаётся запускаемому обработчику события в качестве первого аргумента функции.
Для доступа к объекту события функцию-обработчик следует назначать с указанием одного аргумента. В него будет передана ссылка на объект события.
При назначении через HTML-атрибут объект события доступен по ссылке event
. Для однотипности кода лучше всегда использовать переменную event
для объекта события.
<html> <head> <title>События</title> </head> <body> <input type="button" value="Кнопка"> </body> </html> <script> var button = document.body.firstElementChild; button.onclick = function(event) { alert(event.type); /* 'click' */ } </script>
Стандартные свойства объекта события
Объект любого события является наследником общего объекта-конструктора Event
. Это означает, что все объекты обладают общими свойствами и методами, которые наследуются от Event
. Таких свойств немного и используются из них лишь некоторые.
currentTarget
С момента генерации событие проходит по дереву DOM (перехват и всплытие) и запускает обработчики, установленные на различных элементах. Текущий элемент DOM дерева, на котором в данный момент выполняется обработчик события, определяется свойством event.currentTarget
.
Фактически, currentTarget
содержит ссылку на тот же элемент, что и this
.
<html> <head> <title>События</title> </head> <body> <input type="button" value="Кнопка"> </body> </html> <script> var button = document.body.firstElementChild; button.onclick = function(event) { if (event.currentTarget == this) { alert(event.type + ' на ' + this.tagName); /* 'click на INPUT' */ } } </script>
target
Чтобы в любой момент выполнения события обратиться к целевому элементу, используется свойство event.target
. Оно всегда содержит ссылку на тот элемент, на котором было вызвано событие.
Значение target
отличается от currentTarget
, если обработчик выполняется на стадии перехвата или всплытия.
Свойство target
широко используется. Когда имеется несколько однотипных элементов (например, элементы меню), устанавливается только один обработчик на родительский элемент. А с помощью свойства target
определяется элемент, для которого должно выполниться событие.
<html> <head> <title>События</title> </head> <body> <ul> <li>lorem</li> <li>ipsum</li> <li>dolor</li> <li>sit</li> </ul> </body> </html> <script> var uList = document.body.firstElementChild; uList.onclick = function (event) { this.removeChild(event.target); } </script>
В данном примере клик на любом элементе списка удаляет его. При этом скрипт использует всего один обработчик. Особенно это полезно, когда список элементов заведомо не известен, а создаётся динамически.
eventPhase
Свойство event.eventPhase
указывает, какая фаза события проходит в настоящее время. Оно имеет числовое значение, которое соответствует стадии обработки:
- 0 - никакое событие не обрабатывается.
- 1 - стадия перехвата.
- 2 - стадия цели.
- 3 - стадия всплытия.
timeStamp
Точное время, когда произошло событие, хранится в свойстве event.timeStamp
.
Время представлено как количество миллисекунд, прошедших с начала эпохи Unix (1 января 1970 года по Гринвичу).
type
В свойстве event.type
содержится название события (click
, keypress
и т.п.).
isTrusted
В свойстве event.isTrusted
содержится информация о том, кем вызвано событие. Свойство имеет булевый тип:
true
- событие вызвано действием пользователя или браузером.false
- событие вызвано скриптом, например, с помощью методаdispatchEvent
.
bubbles
Информация о том, будет ли событие всплывать, хранится в свойстве event.bubbles
. Свойство имеет булевый тип:
true
- событие будет всплывать.false
- событие не будет всплывать.
cancelable
Свойство event.cancelable
содержит информацию о том, можно ли отменить стандартные действия браузера, выполняемые по умолчанию. Свойство имеет булевый тип:
true
- действия браузера можно отменить.false
- действия браузера отменить нельзя.
defaultPrevented
Свойство event.defaultPrevented
содержит информацию о том, было ли отменено стандартное действие браузера, выполняемое по умолчанию. Свойство имеет булевый тип:
true
- действие браузера было отменено.false
- действие браузера не было отменено.
preventDefault()
Отменить действия браузера по умолчанию можно простым вызовом
в конце обработчика. Но это можно использовать только внутри обработчиков, установленных через HTML-атрибут или DOM-свойство. Если обработчик устанавливается с помощью метода return false
addEventListener()
, тогда вызов
ни к чему не приведёт. Универсальным способом для отмены действий браузера по умолчанию является встроенный метод return false
event.preventDefault()
.
Вызов preventDefault()
во время любой стадии обработки события отменяет действия браузера. Действия назначенных обработчиков данный метод не отменяет.
<html> <head> <title>События</title> </head> <body> <input type="text" placeholder="Введите текст"> </body> </html> <script> document.body.firstElementChild.onkeypress = function(event) { event.preventDefault(); alert('Отменено'); } </script>
В получившемся поле нельзя ввести текст, используя клавиатуру.
Действия браузера можно отменить не для всех событий. Вызов preventDefault()
на неотменяемом событии результата не даст.
Информацию о состоянии браузерных действий можно получить из булевых свойств: event.cancelable
, event.defaultPrevented
.
stopPropagation()
Для остановки выполнения события на текущем элементе используется метод event.stopPropagation()
.
Данный метод отменяет выполнение обработчиков тех элементов, до которых событие не дошло. Однако, все обработчики текущего элемента будут выполнены даже после вызова stopPropagation()
.
Метод stopPropagation()
не отменяет действия браузера по умолчанию.
<html> <head> <title>События</title> </head> <body> <form name="test"> <input type="text" placeholder="Введите текст" onkeypress="alert('input')"> </form> </body> </html> <script> document.forms.test.addEventListener('keypress', function(event) { alert('form 1'); event.stopPropagation(); }, true); document.forms.test.addEventListener('keypress', function(event) { alert('form 2'); }, true); </script>
Первый обработчик элемента <form>
на стадии перехвата отменяет дальнейшее распространение события keypress
. При этом второй обработчик элемента <form>
всё равно выполняется. А также выполняется действие браузера по умолчанию.
stopImmediatePropagation()
Чтобы отменить выполнение всех невыполненных обработчиков события, даже назначенных текущему элементу, используется метод event.stopImmediatePropagation()
.
Если одному элементу на одно событие назначено несколько обработчиков, то они выполняются в порядке назначения. Если один из них вызывает метод stopImmediatePropagation()
, тогда оставшиеся обработчики не выполняются. Дальнейшее распространение события не происходит.
Метод stopImmediatePropagation()
не отменяет действия браузера по умолчанию.
<html> <head> <title>События</title> </head> <body> <form name="test"> <input type="text" placeholder="Введите текст" onkeypress="alert('input')"> </form> </body> </html> <script> document.forms.test.addEventListener('keypress', function(event) { alert('form 1'); event.stopImmediatePropagation(); }, true); document.forms.test.addEventListener('keypress', function(event) { alert('form 2'); }, true); </script>
Первый обработчик элемента <form>
на стадии перехвата отменяет выполнение последующих обработчиков события keypress
, назначенных текущему элементу, а также предотвращает дальнейшее распространение события. Второй обработчик элемента <form>
не выполняется. Действие браузера по умолчанию всё равно выполняется.