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

При возникновении какого-либо события на элементе страницы браузер автоматически создаёт объект, в котором содержится полезная информация о наступившем событии (например, свойство 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()

Отменить действия браузера по умолчанию можно простым вызовом return false в конце обработчика. Но это можно использовать только внутри обработчиков, установленных через HTML-атрибут или DOM-свойство. Если обработчик устанавливается с помощью метода 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> не выполняется. Действие браузера по умолчанию всё равно выполняется.