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

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

На этом уроке мы рассмотрим для чего предназначен объект event и как его получить. А также познакомимся со свойствами и методами этого объекта.

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

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

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

Пример:

document.addEventListener('click', function(e) {
  // e – объект события, который создаёт браузер и доступный нам через первый аргумент

});
JavaScript - получение дополнительной информации о событии

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

Свойства объекта 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 – координаты клика относительно левого верхнего угла отображаемой страницы.

Свойства объекта события 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

Например, при перемещении мыши (событие mousemove) по веб-странице, вывести координаты курсора в элемент, имеющий id="myP".

<p id="myP"></p>
<script>
document.addEventListener("DOMContentLoaded",function() {
  document.addEventListener("mousemove", function(event) {
    var myP = document.getElementById("myP");
    var X = event.clientX;
    var Y = event.clientY;
    myP.textContent = "X = " + X + "; Y = "+ Y;
  }, false);
},false);
</script>

Если курсор находится над несколькими элементами одновременно, то его получает элемент, который расположен в DOM наиболее глубоко. Курсор может быть только над одним элементов - самым глубоким в DOM (и верхним по z-index).

Отличие 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

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

Для mouseout свойство target указывает на элемент, из которого вышел курсор, а relatedTarget – на который переместилась мышь.

  • relatedTarget (для мыши) - возвращает элемент, который связан с элементом, сгенерировавшим события мыши.
    Например, свойство relatedTarget (для мыши) может быть использовано для получения дополнительной информации о событиях mouseover или mouseout.
    Для события mouseover: свойство target - указывает на элемент, который сейчас находится под курсором; а свойство relatedTarget - на элемент с которого курсор пришёл.
    Для события mouseout: свойство target - указывает на элемент с которого курсор пришёл; а relatedTarget (для мыши) - на элемент, который сейчас находится под курсором.
  • Задачи

    1. Скрытие элемента при клике на него

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

    JavaScript - Перемещение блока с помощью клавиш WASD Решение

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

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

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

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

    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>
            
          Войдите, пожайлуста, в аккаунт, чтобы оставить комментарий.