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

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

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

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

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

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

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

});

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

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

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

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

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.

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 – элемент, к которому прикреплен обработчик события.

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

<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:

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
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 при клике на нем
<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
<style>
#box {
  position: fixed;
  width: 100px;
  height: 100px;
}
</style>

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

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

Решение

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

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

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

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

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

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

Решение

Комментарии ()

  1. Сергей
    19 февраля 2021, 14:11
    Спасибо за подробное и понятное объяснение. Программируя свой сайт, упустил из виду, что 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, а название события (заменяемое в моем случае переменной) стоит перед функцией.
    1. Александр Мальцев
      19 февраля 2021, 16:55
      Пожалуйста!
      Определить поддерживает ли устройство 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;
      });
      
    2. abgar2000
      24 августа 2015, 01:26
      Спасибо за разъяснение. Как, имея несколько кнопок, написать правильный код отлавливания конкретной кнопки? Как идентифицировать кликнутую кнопку (у всех один класс, но в разных местах страницы), на jQuery?
      1. Александр Мальцев
        24 августа 2015, 05:37
        С помощью ключевого слова 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>
        
      2. abgar2000
        23 августа 2015, 01:03
        Доброе время суток.
        Имеется несколько кнопок с одним классом (несколько копий одной кнопки), запускающих, например, форму в окне.
        Как «цивилизованно» (на jQuery) отслеживать кнопу по которой кликнули, чтобы «сделать что-то разное», в зависимости от того, по какой кнопке кликнули? Прописывать if? Или можно реализовать через event?
        Спасибо.
        1. Александр Мальцев
          23 августа 2015, 03:07
          Здравствуйте, 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>
          
        Войдите, пожайлуста, в аккаунт, чтобы оставить комментарий.