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

Свойства и методы объекта события в JavaScript
Содержание:
  1. Как получить информацию о событии?
  2. Свойства и методы объекта события
  3. Свойства объекта события MouseEvent
  4. Свойства объекта события KeyboardEvent
  5. Отличие target от currentTarget
  6. Использование target и relatedTarget
  7. Задачи
  8. Комментарии

В этой статье рассмотрим: как получить информацию о событии, свойства и методы объекта события, свойства MouseEvent и KeyboardEvent, отличие target от currentTarget, пример с relatedTarget.

Как получить информацию о событии?

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

Объект события в соответствии со стандартом всегда передаётся обработчику посредством первого аргумента:

JavaScript
document.addEventListener('click', function(e) {
  // e – объект события, который создал браузер; он содержит детальную информацию о событии

});

Например, выведем детальную информацию в консоль при клике на элемент:

HTML
<div id="center">CENTER</div>

<script>
  const center = document.querySelector('#center');
  center.addEventListener('click', function (e) {
    console.log(`Кнопка: ${e.which}`);
    console.log(`Координаты: (${e.x};${e.y})`);
    console.log(`Тип события: ${e.type}`);
    console.log(`Тег элемента: ${e.currentTarget.tagName}`);
  });
</script>
JavaScript - Дополнительная информация о событии click

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

Свойства объекта Event:

  • bubbles – логическое значение, указывающее на то является ли данное событие всплывающим;
  • cancelable – определяет можно ли событие отменить;
  • cancelBubble – при установке true предотвращает всплытие события, т.е. оно всплывать не будет (является псевдонимом метода stopPropagation);
  • composed – указывает может ли событие всплывать через из теневого DOM (внутреннего DOM конкретного элемента) в обычный DOM документа;
  • currentTarget – элемент, привязанный к обработчику события;
  • defaultPrevented – показывает был ли для события вызван метод preventDefault;
  • eventPhase – число, указывающее фазу процесса распространения события (0 – не обрабатывается, 1 – погружение, 2 – целевой элемент, 3 – всплытие);
  • isTrusted – указывает вызвано ли событие действием пользователя или программно (посредством использования метода dispatchEvent);
  • returnValue – альтернатива для preventDefault;
  • target – элемент, который создал событие;
  • timestamp – время, когда произошло событие;
  • type – тип (имя) события.

Методы объекта Event:

  • preventDefault – отменяет событие, если его конечно можно отменить;
  • stopPropagation – предотвращает всплытие события.

Свойства объекта события MouseEvent

Свойства объекта события при click, dblclick, mousedown иmouseup:

  • altKey, ctrlKey, metaKey и shiftKey – позволяют узнать была ли нажата соответствующая клавиша (т.е., alt, ctrl, meta и shift) при возникновении событии;
  • which – число, сообщающее о том, какая кнопка мыши была нажата (1 - левая кнопка, 2 - средняя кнопка, 3 - правая кнопка);
  • button – также как и which указывает какая кнопка мыши была нажата, чтобы вызвать данное событие (0 – основная кнопка, обычно левая кнопка мыши, 1 – кнопка колёсика или средняя кнопка, 2 – правая кнопка);
  • clientX и clientY – координаты курсора относительно левого верхнего угла viewport;
  • screenX и screenY – координаты клика относительно верхнего левого угла физического экрана или окна браузера;
  • screenX и screenY – координаты клика относительно верхнего левого угла физического экрана или окна браузера;
  • pageX и pageY – координаты клика относительно левого верхнего угла отображаемой страницы.

Например, получим координаты курсора при перемещении по документу (событие mousemove):

JavaScript - Координаты курсора мыши при её перемещении
JavaScript
document.addEventListener('mousemove', function (e) {
  console.log(`Координаты: (${e.x};${e.y})`);
});

Так как в разметке элементы вложены друг в друга, то курсор в большинстве случаев всегда находится одновременно над несколькими элементами. Но взаимодействие всегда осуществляется с тем, кто расположен глубже других (т.е. ближе к нам по оси Z). Если элементы находятся не в основном потоке, то в этом случае с тем, у кого больше значение свойства z-index. Но если элементы имеют одинаковое значение z-index, то тогда ближе к нам будет уже тот, кто из них глубже расположен.

Например, при движении мыши будем выводить информацию о элементе (его значение id), который в данный момент создаёт событие mousemove:

JavaScript
document.addEventListener('mousemove', function (e) {
  console.log(`id: ${e.target.id}`);
});
JavaScript - Информацию о элементе, который в данный момент создаёт событие mousemove

Свойства объекта события KeyboardEvent

Объект KeyboardEvent позволяет обрабатывать взаимодействия пользователя с клавиатурой:

  • altKey, ctrlKey, metaKey и shiftKey – аналогично MouseEvent;
  • keyCode и which – код символа;
  • code – физической код клавиши на клавиатуре;
  • key – значение символа нажатой клавиши;
  • location – возвращает число, сообщающее о расположении клавиши на клавиатуре;
  • repeat – возвращает true, когда нажата клавиши, ввод которой автоматически повторяется.

В большинстве случаев при работе с клавиатурными событиями пользуются свойствами code и key.

JavaScript
document.addEventListener('keyup', function (e) {
  console.log(`type: ${e.type}`);
  console.log(`altKey: ${e.altKey}`);
  console.log(`code: ${e.code}`);
  console.log(`ctrlKey: ${e.ctrlKey}`);
  console.log(`key: ${e.key}`);
  console.log(`keyCode: ${e.keyCode}`);
  console.log(`metaKey: ${e.metaKey}`);
  console.log(`repeat: ${e.repeat}`);
  console.log(`shiftKey: ${e.shiftKey}`);
  console.log(`which: ${e.which}`);
});
JavaScript - Получение некоторых свойств KeyboardEvent при наступлении события keyup

Отличие target от currentTarget

События в браузере по умолчанию всплывают. Из-за этого:

  • target – элемент, который вызвал событие;
  • currentTarget – элемент, к которому прикреплен обработчик события.

Например, рассмотрим этот код:

HTML
<body>
  <div class="outer">
    <div class="inner">...</div>
  </div>
</body>

При клике на div.inner будет создано событие click, которое будет подниматься от узла div.inner до window (проходя через div.outer, body, html и document соответственно - при условии, что мы не отключили всплытие события с помощью нашего js-кода).

При этом обработчик события мы можем прикрепить к любому из этих узлов (div.inner, div.outer, body, html, document, window). Разница между currentTarget и target в том, что target всегда будет указывать на источник события (.inner), а currentTarget на элемент к которому мы прикрепили обработчик.

Например, прикрепим обработчик к элементу .outer:

JavaScript
const outer = document.querySelector('.outer');
outer.addEventListener('click', function (e) {
  const $target = e.target;
  const $currentTarget = e.currentTarget;
  // выведем значения в консоль
  console.log($target);
  console.log($currentTarget);
});

При клике на элемент .inner событие click будет всплывать. В обработчике, который мы назначили элементу .outer, свойство target будет указывать на элемент, который вызвал событие, а currentTarget - на элемент, к которому этот обработчик добавлен, т.е. на .outer.

JavaScript - Отличие target от currentTarget

Использование target и relatedTarget

Свойство relatedTarget предназначено для определения дополнительной цели, связанной с событием.

Например:

  • для события mouseover свойство target указывает элемент, на который курсор был перемещён, а relatedTarget – с какого;
  • для mouseout свойство target указывает элемент, с которого вышел курсор, а relatedTarget – на который он вошёл.

Пример:

JavaScript - Использование target и relatedTarget для событий mouseover и mouseout
JavaScript
document.addEventListener('mouseover', function (e) {
  console.log(`type: ${e.type}`);
  console.log(`target: ${e.target.tagName.toLowerCase()}.${e.target.className}`);
  console.log(`relatedTarget: ${e.relatedTarget.tagName.toLowerCase()}.${e.relatedTarget.className}`);
});
document.addEventListener('mouseout', function (e) {
  console.log(`type: ${e.type}`);
  console.log(`target: ${e.target.tagName.toLowerCase()}.${e.target.className}`);
  console.log(`relatedTarget: ${e.relatedTarget.tagName.toLowerCase()}.${e.relatedTarget.className}`);
});

Задачи

1. Удаление элемента при клике на нем

На странице имеется 9 элементов li, расположенные в .items.

Задача по JavaScript - Удалить элемент из DOM при клике на нем
HTML
<ul class="items">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
</ul>

Необходимо написать JavaScript сценарий, который будет при клике на элементе удалять его из DOM.

Решение

2. Перемещение блока с помощью клавиш «WASD»

Имеется элемент:

JavaScript - Перемещение блока с помощью клавиш WASD
HTML
<style>
#box {
  position: fixed;
  width: 100px;
  height: 100px;
}
</style>

<div id="box"></div>

Нужно создать код, который будет при нажатии клавиш «WASD» перемещать элемент #box по странице.

Решение

3. Одновременное нажатие кнопок

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

JavaScript - Вывод сообщения в верхней части экрана при одновременном нажатии клавиш Z и X

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

HTML
<div class="messages__item">Сообщение</div>

Помещать создаваемые сообщения необходимо в элемент .messages.

Решение

Комментарии: 8

Иван Борисович
Иван Борисович

Александр и Всем читателям добры день, возможно мой вопрос будет глупым для опытных читателей, но очень мучает этот вопрос касаемо темы Event, мне как начинающему очень тяжело понять Для Чего Именно необходимо использовать Event? Только лишь для того чтобы вывести всю информацию о событии в консоль, и в дальнейшим копировать нужное свойство из полученных данных и вставить его для работы дальнейшей? К примеру мы получили свойства, увидели их в консоли, и что дальше необходимо делать? Или же я просто не совсем так понимаю настоящую суть Объекта События Event? Подскажите пожалуйста более опытные единомышленники! Заранее Благодарю!

Александр Мальцев
Александр Мальцев

Добрый день! Event используется довольно часто.

Например, для отправки формы через AJAX. Этот функционал нельзя написать без использования event, так как нужно в этом случае отменить стандартное поведение браузера:
event.preventDefault();
Кроме этого, на странице может быть несколько форм. В этой ситуации, можно использовать один обработчик и не создавать его для каждой из них. Но тогда в обработчике необходимо знать для какой формы произошел submit, чтобы дальше в коде обрабатывать именно эту форму. И тут конечно без event тоже не обойтись.

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

Например, event применялся в примере с использованием FileReader. Можете посмотреть его и разобраться для чего он там нужен.
Сергей
Сергей
Спасибо за подробное и понятное объяснение. Программируя свой сайт, упустил из виду, что click на мобильных не всегда правильно обрабатывается. Хотя в 90% addEventListener прослушивает на сайте только `click`, а `touchstart`не слушает. Решил ввести глобальную переменную const clickTouch = (!isMobile)? `click`: `touchstart`; и через тернарный оператор менять тип события в зависимости от const isMobile = window.matchMedia(«only screen and (max-width: 768px)»).matches. Соответственно в слушателе использовать, например, buttonM.addEventListener(clickTouch, showmobMenu); Но поскольку придется менять на всем сайте, хотел бы сначала проконсультироваться с опытным специалистом, с вами. По вашему мнению, такое решение надежно и стоит использовать или есть другая альтернатива? Думаю, что можно было вместо проверки на мобильный делать проверку на event.type, но такая проверка проходит внутри функции addEventListener, а название события (заменяемое в моем случае переменной) стоит перед функцией.
Александр Мальцев
Александр Мальцев
Пожалуйста!
Определить поддерживает ли устройство touch можно так:
function hasTouchDevice() {
  return !!('ontouchstart' in window || navigator.maxTouchPoints);
}
if (hasTouchDevice()) {
  // устройство поддерживает touch
} else {
  // устройство не поддерживает touch
}
Но ориентироваться на это не очень хорошая идея. Т.к. сейчас имеется достаточного много устройств с сенсорным экраном и мышью (например, ноутбуки).
function hasTouchDevice() {
  return !!('ontouchstart' in window || navigator.maxTouchPoints);
}
const typeEvent = hasTouchDevice() ? 'touchend' : 'click';
document.addEventListener(typeEvent, function (e) {
  console.log(e.type);
});
В этом случае typeEvent будет равен 'touchend' и пользователь на ноутбуке с сенсорным экраном сможет работать с сайтом только посредством касаний, а посредством мыши нет.

Наверно, лучше решение — это будет использовать сразу 2 события. Но, чтобы функция 2 раза не выполнилась использовать preventDefault:
const myFunc = function (e) {
  event.preventDefault();

  console.log(e.type);
}
document.addEventListener('touchend', myFunc);
document.addEventListener('click', myFunc);
Если используете jQuery, то так:
$(document).on('click touchend', function (e) {
  console.log(e.type);

  return false;
});
Аноним
Аноним
Спасибо за разъяснение. Как, имея несколько кнопок, написать правильный код отлавливания конкретной кнопки? Как идентифицировать кликнутую кнопку (у всех один класс, но в разных местах страницы), на jQuery?
Александр Мальцев
Александр Мальцев
С помощью ключевого слова this:

<button type="button">Кнопка 1</button>
<button type="button">Кнопка 2</button>
<button type="button">Кнопка 3</button>
<button type="button">Кнопка 4</button>

<script>
$(function() {
  $('button').click(function() {
    //скрыть кнопку на которую нажали
    //this - это кнопка на которую Вы нажали 
    $(this).hide();
    //или например можно изменить текст кнопки, на которую Вы нажали
    //$(this).text("Вы нажали на эту кнопку");
    //или сделать что-то другое
  });
});
</script>
Аноним
Аноним
Доброе время суток.
Имеется несколько кнопок с одним классом (несколько копий одной кнопки), запускающих, например, форму в окне.
Как «цивилизованно» (на jQuery) отслеживать кнопу по которой кликнули, чтобы «сделать что-то разное», в зависимости от того, по какой кнопке кликнули? Прописывать if? Или можно реализовать через event?
Спасибо.
Александр Мальцев
Александр Мальцев
Здравствуйте, abgar2000.
Через объект event Вы можете только узнать больше информации о произошедшем событии. Полученная информация не даст Вам сделать «что-то разное». Т.е. чтобы сделать что-то разное нужно эту информацию с чем-то сравнивать, а для этого необходимо использовать конструкцию if.
Ситуации, когда конструкцию if можно не использовать, если Вы хотите что-то сделать с самим элементом, или с его родителем или ребенком. Для этого с помощью объекта event Вы получаете элемент, который сгенерировал событие (event.target). Получив этот объект, вы можете изменить значение его атрибутов, изменить текст его ребёнка и т.п. Но если Вы хотите что-то сделать не связанное с этим объектом (или с его предками и потомками), то выполнить это можно только через условия.

Например, если Вы хотите посмотреть всю информацию объекта event о произошедшем событии, то можно написать следующий код:
<!--Кнопки-->
<button type="button" value="Значение">Текст кнопки</button>

<!--Вывести в консоль всю информацию о событии с помощью JavaScript-->
<script>
  document.addEventListener("DOMContentLoaded",function() {
    var buttons = document.getElementsByTagName("BUTTON");
    //подписываем все кнопки на события
    for (var i=0; i<elements.length; i++) {
      elements[i].addEventListener("click", myEvent, false);
    }
    //функция, которая будет выводить всю информацию в консоль браузера
    function myEvent(event) {
      for (var property in event) {
        console.log(property+" : "+event[property]);
      }
    }
  });
</script>

<!--Вывести в консоль всю информацию о событии на jQuery-->
<script>
  $(function() {
    $("button").click(function(event) {
      for (var property in event) {
        console.log(property+" : "+event[property]);
      }
    });
  });
</script>