Сколько есть возможных значений event button
Перейти к содержимому

Сколько есть возможных значений event button

  • автор:

Основы событий мыши

В этой главе мы более детально рассмотрим события мыши и их свойства.

Сразу заметим: эти события бывают не только из-за мыши, но и эмулируются на других устройствах, в частности, на мобильных, для совместимости.

Типы событий мыши

Мы уже видели некоторые из этих событий:

mousedown/mouseup Кнопка мыши нажата/отпущена над элементом. mouseover/mouseout Курсор мыши появляется над элементом и уходит с него. mousemove Каждое движение мыши над элементом генерирует это событие. click Вызывается при mousedown , а затем mouseup над одним и тем же элементом, если использовалась левая кнопка мыши. dblclick Вызывается двойным кликом на элементе. contextmenu Вызывается при попытке открытия контекстного меню, как правило, нажатием правой кнопки мыши. Но, заметим, это не совсем событие мыши, оно может вызываться и специальной клавишей клавиатуры.

…Есть также несколько иных типов событий, которые мы рассмотрим позже.

Порядок событий

Как вы можете видеть из приведённого выше списка, действие пользователя может вызвать несколько событий.

Например, клик мышью вначале вызывает mousedown , когда кнопка нажата, затем mouseup и click , когда она отпущена.

В случае, когда одно действие инициирует несколько событий, порядок их выполнения фиксирован. То есть обработчики событий вызываются в следующем порядке: mousedown → mouseup → click .

Кликните на кнопку ниже, и вы увидите события. Также попробуйте двойной клик.

В окне теста ниже все события мыши записываются, и если задержка между ними более 1 секунды, то они разделяются горизонтальной чертой.

Кроме того, мы можем видеть свойство button , которое позволяет нам определять кнопку мыши; это объясняется ниже.

Кнопки мыши

События, связанные с кликом, всегда имеют свойство button , которое позволяет получить конкретную кнопку мыши.

Обычно мы не используем его для событий click и contextmenu , потому что первое происходит только при щелчке левой кнопкой мыши, а второе – только при щелчке правой кнопкой мыши.

С другой стороны, обработчикам mousedown и mouseup может потребоваться event.button , потому что эти события срабатывают на любую кнопку, таким образом button позволяет различать «нажатие правой кнопки» и «нажатие левой кнопки».

Возможными значениями event.button являются:

Состояние кнопки event.button
Левая кнопка (основная) 0
Средняя кнопка (вспомогательная) 1
Правая кнопка (вторичная) 2
Кнопка X1 (назад) 3
Кнопка X2 (вперёд) 4

Большинство мышек имеют только левую и правую кнопку, поэтому возможные значения это 0 или 2. Сенсорные устройства также генерируют аналогичные события, когда кто-то нажимает на них.

Также есть свойство event.buttons , в котором все нажатые в данный момент кнопки представлены в виде целого числа, по одному биту на кнопку. На практике это свойство используется очень редко, вы можете найти подробную информацию по адресу MDN, если вам это когда-нибудь понадобится.

В старом коде вы можете встретить event.which свойство – это старый нестандартный способ получения кнопки с возможными значениями:

  • event.which == 1 – левая кнопка,
  • event.which == 2 – средняя кнопка,
  • event.which == 3 – правая кнопка.

На данный момент event.which устарел, нам не следует его использовать.

Средняя кнопка сейчас – скорее экзотика, и используется очень редко.

Модификаторы: shift, alt, ctrl и meta

Все события мыши включают в себя информацию о нажатых клавишах-модификаторах.

  • shiftKey : Shift
  • altKey : Alt (или Opt для Mac)
  • ctrlKey : Ctrl
  • metaKey : Cmd для Mac

Они равны true , если во время события была нажата соответствующая клавиша.

Например, кнопка внизу работает только при комбинации Alt + Shift +клик:

В Windows и Linux клавишами-модификаторами являются Alt , Shift и Ctrl . На Mac есть ещё одна: Cmd , которой соответствует свойство metaKey .

В большинстве приложений, когда в Windows/Linux используется Ctrl , на Mac используется Cmd .

То есть, когда пользователь Windows нажимает Ctrl + Enter и Ctrl + A , пользователь Mac нажимает Cmd + Enter или Cmd + A , и так далее.

Поэтому, если мы хотим поддерживать такие комбинации, как Ctrl +клик, то для Mac имеет смысл использовать Cmd +клик. Это удобней для пользователей Mac.

Даже если мы и хотели бы заставить людей на Mac использовать именно Ctrl +клик, это довольно сложно. Проблема в том, что левый клик в сочетании с Ctrl интерпретируется как правый клик на MacOS и генерирует событие contextmenu , а не click как на Windows/Linux.

Поэтому, если мы хотим, чтобы пользователям всех операционных систем было удобно, то вместе с ctrlKey нам нужно проверять metaKey .

Для JS-кода это означает, что мы должны проверить if (event.ctrlKey || event.metaKey) .

Комбинации клавиш хороши в качестве дополнения к рабочему процессу. Так что, если посетитель использует клавиатуру – они работают.

Но если на их устройстве его нет – тогда должен быть способ жить без клавиш-модификаторов.

Координаты: clientX/Y, pageX/Y

Все события мыши имеют координаты двух видов:

  1. Относительно окна: clientX и clientY .
  2. Относительно документа: pageX и pageY .

Мы уже рассмотрели разницу между ними в главе Координаты.

Если в кратце, то относительные координаты документа pageX/Y отсчитываются от левого верхнего угла документа и не меняются при прокрутке страницы, в то время как clientX/Y отсчитываются от левого верхнего угла текущего окна. Когда страница прокручивается, они меняются.

Например, если у нас есть окно размером 500×500, и курсор мыши находится в левом верхнем углу, то значения clientX и clientY равны 0 , независимо от того, как прокручивается страница.

А если мышь находится в центре окна, то значения clientX и clientY равны 250 независимо от того, в каком месте документа она находится и до какого места документ прокручен. В этом они похожи на position:fixed .

Наведите курсор мыши на поле ввода, чтобы увидеть clientX/clientY (пример находится в iframe , поэтому координаты определяются относительно этого iframe ):

Координаты относительно документа pageX , pageY отсчитываются не от окна, а от левого верхнего угла документа. Подробнее о координатах вы можете узнать в главе Координаты.

Отключаем выделение

Двойной клик мыши имеет побочный эффект, который может быть неудобен в некоторых интерфейсах: он выделяет текст.

Например, двойной клик на текст ниже выделяет его в дополнение к нашему обработчику:

Если зажать левую кнопку мыши и, не отпуская кнопку, провести мышью, то также будет выделение, которое в интерфейсах может быть «не кстати».

Есть несколько способов запретить выделение, о которых вы можете прочитать в главе Selection и Range.

В данном случае самым разумным будет отменить действие браузера по умолчанию при событии mousedown , это отменит оба этих выделения:

Теперь выделенный жирным элемент не выделяется при двойном клике, а также на нём нельзя начать выделение, зажав кнопку мыши.

Заметим, что текст внутри него по-прежнему можно выделить, если начать выделение не на самом тексте, а до него или после. Обычно это нормально воспринимается пользователями.

Если мы хотим отключить выделение для защиты содержимого страницы от копирования, то мы можем использовать другое событие: oncopy .

Если вы попытаетесь скопировать текст в <div> , у вас это не получится, потому что срабатывание события oncopy по умолчанию запрещено.

Конечно, пользователь имеет доступ к HTML-коду страницы и может взять текст оттуда, но не все знают, как это сделать.

Итого

События мыши имеют следующие свойства:

Клавиши-модификаторы ( true если нажаты): altKey , ctrlKey , shiftKey и metaKey (Mac).

  • Если вы планируете обработать Ctrl , то не забудьте, что пользователи Mac обычно используют Cmd , поэтому лучше проверить if (e.metaKey || e.ctrlKey) .

Координаты относительно окна: clientX/clientY .

Координаты относительно документа: pageX/pageY .

Действие по умолчанию события mousedown – начало выделения, если в интерфейсе оно скорее мешает, его можно отменить.

В следующей главе мы поговорим о событиях, которые возникают при передвижении мыши, и об отслеживании смены элементов под указателем.

Задачи

Выделяемый список

Создайте список, в котором элементы могут быть выделены, как в файловых менеджерах.

Введение в события

События — это действия или случаи, возникающие в программируемой вами системе, о которых система сообщает вам для того, чтобы вы могли с ними взаимодействовать. Например, если пользователь нажимает кнопку на веб-странице, вы можете ответить на это действие, отобразив информационное окно. В этой статье мы обсудим некоторые важные концепции, связанные с событиями, и посмотрим, как они работают в браузерах. Эта статья не является исчерпывающим источником по этой теме — здесь только то, что вам нужно знать на этом этапе.

Предпосылки: Базовая компьютерная грамотность, базовое понимание HTML и CSS, Первые шаги в JavaScript.
Задача: Понять фундаментальную теорию событий, как они работают в браузерах и как события могут различаться в разных средах программирования.

Серия удачных событий

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

В Web события запускаются внутри окна браузера и, как правило, прикрепляются к конкретному элементу, который в нем находится. Это может быть один элемент, набор элементов, документ HTML, загруженный на текущей вкладке, или все окно браузера. Существует множество различных видов событий, которые могут произойти, например:

  • Пользователь кликает мышью или наводит курсор на определённый элемент.
  • Пользователь нажимает клавишу на клавиатуре.
  • Пользователь изменяет размер или закрывает окно браузера.
  • Завершение загрузки веб-страницы.
  • Отправка данных через формы.
  • Воспроизведение видео, пауза или завершение воспроизведения.
  • Произошла ошибка.

Подробнее о событиях можно посмотреть в Справочнике по событиям.

Каждое доступное событие имеет обработчик событий — блок кода (обычно это функция JavaScript, вводимая вами в качестве разработчика), который будет запускаться при срабатывании события. Когда такой блок кода определён на запуск в ответ на возникновение события, мы говорим, что мы регистрируем обработчик событий. Обратите внимание, что обработчики событий иногда называют **слушателями событий (от англ. event listeners). Они в значительной степени взаимозаменяемы для наших целей, хотя, строго говоря, они работают вместе. Слушатель отслеживает событие, а обработчик — это код, который запускается в ответ на событие.

Примечание: Важно отметить, что веб-события не являются частью основного языка JavaScript. Они определены как часть JavaScript-API, встроенных в браузер.

Простой пример

Рассмотрим простой пример. Вы уже видели события и обработчики событий во многих примерах в этом курсе, но давайте повторим для закрепления информации. В этом примере у нас есть кнопка <button> , при нажатии которой цвет фона изменяется случайным образом:

JavaScript выглядит так:

В этом коде мы сохраняем ссылку на кнопку внутри переменной btn типа const , используя функцию Document.querySelector() . Мы также определяем функцию, которая возвращает случайное число. Третья часть кода — обработчик события. Переменная btn указывает на элемент <button> — для этого типа объекта существуют возникающие при определённом взаимодействии с ним события, а значит, возможно использование обработчиков событий. Мы отслеживаем момент возникновения события при щелчке мышью, связывая свойство обработчика события onclick с анонимной функцией, генерирующей случайный цвет RGB и устанавливающей его в качестве цвета фона элемента <body> .

Этот код теперь будет запускаться всякий раз, когда возникает событие при нажатии на элемент <button> — всякий раз, когда пользователь щёлкает по нему.

Пример вывода выглядит следующим образом:

События не только для веб-страниц

События, как понятие, относятся не только к JavaScript — большинство языков программирования имеют модель событий, способ работы которой часто отличается от модели в JavaScript. Фактически, даже модель событий в JavaScript для веб-страниц отличается от модели событий для просто JavaScript, поскольку используются они в разных средах.

Например, Node.js — очень популярная среда исполнения JavaScript, которая позволяет разработчикам использовать JavaScript для создания сетевых и серверных приложений. Модель событий Node.js основана на том, что существуют обработчики, отслеживающие события, и эмиттеры (передатчики), которые периодически генерируют события. В общем-то, это похоже на модель событий в JavaScript для веб-страниц, но код совсем другой. В этой модели используется функция on() для регистрации обработчиков событий, и функция once() для регистрации обработчика событий, который отключается после первого срабатывания. Хорошим примером использования являются протоколы событий HTTP connect event docs.

Вы также можете использовать JavaScript для создания кросс-браузерных расширений — улучшения функциональности браузера с помощью технологии WebExtensions. В отличии от модели веб-событий здесь свойства обработчиков событий пишутся в так называемом регистре CamelCase (например, onMessage , а не onmessage ) и должны сочетаться с функцией addListener . См. runtime.onMessage page для примера.

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

Способы использования веб-событий

Существует множество различных способов добавления кода обработчика событий на веб-страницы так, чтобы он срабатывал при возникновении соответствующего события. В этом разделе мы рассмотрим различные механизмы и обсудим, какие из них следует использовать.

Свойства обработчика событий

В этом курсе вы уже сталкивались со свойствами, связываемыми с алгоритмом работы обработчика событий. Вернёмся к приведённому выше примеру:

В данной ситуации свойство onclick — это свойство обработчика события. В принципе это обычное свойство кнопки как элемента (наравне с btn.textContent или btn.style ), но оно относится к особому типу. Если вы установите его равным какому-нибудь коду, этот код будет запущен при возникновении события (при нажатии на кнопку).

Для получения того же результата, вы также можете присвоить свойству обработчика имя уже описанной функции (как мы видели в статье Создайте свою функцию):

Давайте теперь поэкспериментируем с другими свойствами обработчика событий.

Создайте локальную копию файла random-color-eventhandlerproperty.html и откройте её в своём браузере. Это всего лишь копия простого примера про случайные цвета, который мы уже разобрали в этой статье. Теперь попробуйте изменить btn.onclick на следующие значения и понаблюдайте за результатами:

    и btn.onblur — Цвет изменится, когда кнопка будет сфокусирована или не сфокусирована (попробуйте нажать Tab, чтобы выбрать кнопку или убрать выбор). Эти свойства часто применяются для отображения информации о том, как заполнить поля формы, когда они сфокусированы, или отобразить сообщение об ошибке, если поле формы было заполнено с неправильным значением. — Цвет будет изменяться только при двойном щелчке. , window.onkeydown , window.onkeyup — Цвет будет меняться при нажатии клавиши на клавиатуре, причём keypress ссылается на обычное нажатие (нажатие кнопки и последующее её отпускание как одно целое), в то время как keydown и keyup разделяют действия на нажатие клавиши и отпускание, и ссылаются на них соответственно. Обратите внимание, что это не работает, если вы попытаетесь зарегистрировать этот обработчик событий на самой кнопке — его нужно зарегистрировать на объекте window, который представляет все окно браузера. и btn.onmouseout — Цвет будет меняться при наведении указателя мыши на кнопку или когда указатель будет отводиться от кнопки соответственно.

Некоторые события очень общие и доступны практически в любом месте (например, обработчик onclick может быть зарегистрирован практически для любого элемента), тогда как некоторые из них более конкретны и полезны только в определённых ситуациях (например, имеет смысл использовать onplay (en-US) только для определённых элементов, таких как <video> ).

Встроенные обработчики событий — не используйте их

Самый ранний из введённых в сеть Web методов регистрации обработчиков событий базируется на HTML атрибутах (встроенные обработчики событий):

Примечание: вы можете найти полный исходник кода из этого примера на GitHub (также взгляните на его выполнение).

Значение атрибута — это буквально код JavaScript, который вы хотите запустить при возникновении события. В приведённом выше примере вызывается функция, определённая внутри элемента <script> на той же странице, но вы также можете вставить JavaScript непосредственно внутри атрибута, например:

Для многих свойств обработчика событий существуют эквиваленты в виде атрибутов HTML. Однако, не рекомендуется их использовать — это считается плохой практикой. Использование атрибутов для регистрации обработчика событий кажется простым и быстрым методом, но такое описание обработчиков также скоро становится неудобным и неэффективным.

Более того, не рекомендуется смешивать HTML и JavaScript файлы, так как в дальнейшем такой код становится сложнее с точки зрения обработки (парсинга). Лучше держать весь JavaScript в одном месте. Также, если он находится в отдельном файле, вы можете применить его к нескольким документам HTML.

Даже при работе только в одном файле использование встроенных обработчиков не является хорошей идеей. Ладно, если у вас одна кнопка, но что, если у вас их 100? Вам нужно добавить в файл 100 атрибутов; обслуживание такого кода очень быстро превратится в кошмар. С помощью JavaScript вы можете легко добавить функцию обработчика событий ко всем кнопкам на странице независимо от того, сколько их было.

Обратите внимание, что для перебора всех элементов, которые содержит объект NodeList , можно воспользоваться встроенным методом forEach() :

Примечание: Разделение логики вашей программы и вашего контента также делает ваш сайт более дружественным к поисковым системам.

Функции addEventListener() и removeEventListener()

Новый тип механизма событий определён в спецификации Document Object Model (DOM) Level 2 Events, которая предоставляет браузеру новую функцию — addEventListener() . Работает она аналогично свойствам обработчика событий, но синтаксис совсем другой. Наш пример со случайным цветом мог бы выглядеть и так:

Примечание: вы можете найти исходный код из этого примера на GitHub (также взгляните на его выполнение).

Внутри функции addEventListener() мы указываем два параметра — имя события, для которого мы хотим зарегистрировать этот обработчик, и код, содержащий функцию обработчика, которую мы хотим запустить в ответ. Обратите внимание, что будет целесообразно поместить весь код внутри функции addEventListener() в анонимную функцию, например:

Этот механизм имеет некоторые преимущества по сравнению с более старыми механизмами, рассмотренными ранее. Например, существует аналогичная функция removeEventListener() , которая удаляет ранее добавленный обработчик. Это приведёт к удалению набора обработчиков в первом блоке кода в этом разделе:

Это не важно для простых небольших программ, но для более крупных и более сложных программ он может повысить эффективность очистки старых неиспользуемых обработчиков событий. Кроме того, это позволяет вам иметь одну и ту же кнопку, выполняющую различные действия в разных обстоятельствах — все, что вам нужно сделать, это добавить/удалить обработчики событий, если это необходимо.

Также вы можете зарегистрировать несколько обработчиков для одного и того же события на элементе. Следующие два обработчика не будут применяться:

Поскольку вторая строка будет перезаписывать значение onclick , установленное первой. Однако, если:

Обе функции будут выполняться при щелчке элемента.

Кроме того, в этом механизме событий имеется ряд других мощных функций и опций. Эта тема выходит за рамки данной статьи, но если вы хотите изучить подробнее, переходите по ссылкам: Метод EventTarget.addEventListener() и Метод EventTarget.removeEventListener().

Какой механизм мне использовать?

Из трёх механизмов определённо не нужно использовать атрибуты событий HTML. Как упоминалось выше, это устаревшая и плохая практика.

Остальные два являются относительно взаимозаменяемыми, по крайней мере для простых целей

  • Свойства обработчика событий имеют меньшую мощность и параметры, но лучше совместимость между браузерами (поддерживается ещё в Internet Explorer 8). Вероятно, вам следует начать с них, когда вы учитесь.
  • События уровня 2 DOM ( addEventListener() и т. д.) являются более мощными, но также могут стать более сложными и хуже поддерживаться (поддерживается ещё в Internet Explorer 9). Вам также стоит поэкспериментировать с ними и стремиться использовать их там, где это возможно.

Основные преимущества третьего механизма заключаются в том, что при необходимости можно удалить код обработчика событий, используя removeEventListener() , и так же можно добавить несколько элементов-обработчиков того же типа к элементам. Например, вы можете вызвать addEventListener(‘click’, function() <. >) для элемента несколько раз, с разными функциями, указанными во втором аргументе. Это невозможно при использовании свойств обработчика событий, поскольку любые последующие попытки установить свойство будут перезаписывать более ранние, например:

Примечание: Если вам требуется поддержка браузеров старше Internet Explorer 8 в вашем проекте, вы можете столкнуться с трудностями, так как такие старые браузеры используют старые модели событий из более новых браузеров. Но не бойтесь, большинство библиотек JavaScript (например, jQuery ) имеют встроенные функции, которые абстрагируют различия между браузерами. Не беспокойтесь об этом слишком много на этапе вашего учебного путешествия.

Другие концепции событий

Рассмотрим некоторые современные концепции, имеющие отношение к событиям. На данный момент не обязательно понимать их полностью, но представление о них поможет лучше понять некоторые модели кода, с которыми вы, вероятно, столкнётесь.

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

Иногда внутри функции обработчика событий вы можете увидеть параметр, заданный с таким именем, как event , evt или просто e . Называется он объектом события и он автоматически передаётся обработчикам событий для предоставления дополнительных функций и информации. Например, давайте немного перепишем наш пример со случайным цветом:

Примечание: вы можете найти исходник кода для этого примера на GitHub (также взгляните на его выполнение).

Итак в коде выше мы включаем объект события e в функцию, а в функции — настройку стиля фона для e.target , который является кнопкой. Свойство объекта события target всегда является ссылкой на элемент, с которым только что произошло событие. Поэтому в этом примере мы устанавливаем случайный цвет фона на кнопке, а не на странице.

Примечание: Вместо e / evt / event можно использовать любое имя для объекта события, которое затем можно использовать для ссылки на него в функции обработчика событий. e / evt / event чаще всего используются разработчиками, потому что они короткие и легко запоминаются. И хорошо придерживаться стандарта.

e.target применяют, когда нужно установить один и тот же обработчик событий на несколько элементов и, когда на них происходит событие, применить определённое действие к ним ко всем. Например, у вас может быть набор из 16 плиток, которые исчезают при нажатии. Полезно всегда иметь возможность просто указать, чтобы объект исчез, как e.target , вместо того, чтобы выбирать его более сложным способом. В следующем примере (см. исходный код на useful-eventtarget.html,а как он работает можно посмотреть здесь), мы создаём 16 элементов <div> с использованием JavaScript. Затем мы выберем все из них, используя document.querySelectorAll() , и с помощью цикла for выберем каждый из них, добавив обработчик onclick к каждому так, чтобы случайный цвет применялся к каждому клику:

Результат выглядит следующим образом (попробуйте щёлкнуть по нему):

Большинство обработчиков событий, с которыми вы столкнулись, имеют только стандартный набор свойств и функций (методов), доступных для объекта события (см. Event для ссылки на полный список). Однако некоторые более продвинутые обработчики добавляют специальные свойства, содержащие дополнительные данные, которые им необходимо выполнять. Например, Media Recorder API (en-US) имеет событие, доступное для данных, которое срабатывает, когда записано какое-либо аудио или видео и доступно для выполнения чего-либо (например, для сохранения или воспроизведения). Соответствующий объект события ondataavailable handler имеет свойство данных, содержащее записанные аудио- или видеоданные, чтобы вы могли получить к нему доступ и что-то сделать с ним.

Предотвращение поведения по умолчанию

Иногда бывают ситуации, когда нужно остановить событие, выполняющее то, что оно делает по умолчанию. Наиболее распространённым примером является веб-форма, например, пользовательская форма регистрации. Когда вы вводите данные и нажимаете кнопку отправки, естественное поведение заключается в том, что данные должны быть отправлены на указанную страницу на сервере для обработки, а браузер перенаправляется на страницу с сообщением об успехе (или остаться на той же странице, если другое не указано).

Но если пользователь отправил данные не правильно, как разработчик, вы хотите остановить отправку на сервер и выдать сообщение об ошибке с информацией о том, что не так и что нужно сделать. Некоторые браузеры поддерживают функции автоматической проверки данных формы, но, поскольку многие этого не делают, вам не следует полагаться на них и выполнять свои собственные проверки валидации. Давайте посмотрим на простой пример.

Простая форма HTML, в которой требуется ввести ваше имя и фамилию:

В JavaScript мы реализуем очень простую проверку внутри обработчика события onsubmit (событие «отправить» запускается в форме, когда оно отправлено), который проверяет, пусты ли текстовые поля. Если они пусты, мы вызываем функцию preventDefault() объекта события, которая останавливает отправку формы, а затем выводит сообщение об ошибке в абзаце ниже нашей формы, чтобы сообщить пользователю, что не так:

Очевидно, что это довольно слабая проверка формы — это не помешает пользователю отправить форму с пробелами или цифрами, введёнными в поля, но для примера подходит. Вывод выглядит следующим образом:

Примечание: чтобы увидеть исходный код, откройте preventdefault-validation.html (также запустите здесь).

Всплытие и перехват событий

Последним предметом для рассмотрения в этой теме является то, с чем вы не часто будете сталкиваться, но это может стать настоящей головной болью, если вы не поймёте, как работает следующий механизм. Всплытие и перехват событий — два механизма, описывающих, что происходит, когда два обработчика одного и того же события активируются на одном элементе. Посмотрим на пример. Чтобы сделать это проще — откройте пример show-video-box.html в одной вкладке и исходный код в другой вкладке. Он также представлен ниже:

Это довольно простой пример, который показывает и скрывает <div> с элементом <video> внутри него:

При нажатии на кнопку <button> , изменяется атрибут класса элемента <div> с hidden на showing (CSS примера содержит эти два класса, которые размещают блок вне экрана и на экране соответственно):

Затем мы добавляем ещё пару обработчиков событий onclick. Первый к <div> , а второй к <video> . Идея заключается в том, чтобы при щелчке по области <div> вне зоны видео поле снова скрылось, а при клике в области <video> видео начало воспроизводиться.

Но есть проблема: когда вы нажимаете на видео, оно начинает воспроизводиться, но одновременно вызывает скрытие <div> . Это связано с тем, что видео находится внутри <div>, это часть его, поэтому нажатие на видео фактически запускает оба вышеуказанных обработчика событий.

Всплытие и перехват событий — концепция выполнения

Когда событие инициируется элементом, который имеет родительские элементы (например, <video> в нашем случае), современные браузеры выполняют две разные фазы — фазу захвата и фазу всплытия.

На стадии захвата происходит следующее:

  • Браузер проверяет, имеет ли самый внешний элемент ( <html> ) обработчик события onclick , зарегистрированный на нем на этапе захвата и запускает его, если это так.
  • Затем он переходит к следующему элементу внутри <html> и выполняет то же самое, затем следующее и так далее, пока не достигнет элемента, на который на самом деле нажали.

На стадии всплытия происходит полная противоположность:

  • Браузер проверяет, имеет ли элемент, который был фактически нажат, обработчик события onclick , зарегистрированный на нем в фазе всплытия, и запускает его, если это так.
  • Затем он переходит к следующему непосредственному родительскому элементу и выполняет то же самое, затем следующее и так далее, пока не достигнет элемента <html> .

(Нажмите на изображение, чтобы увеличить диаграмму)

В современных браузерах по умолчанию все обработчики событий регистрируются в фазе всплытия. Итак, в нашем текущем примере, когда вы нажимаете видео, событие click вызывается из элемента <video> наружу, в элемент <html> . По пути:

  • Он находит обработчик video.onclick. и запускает его, поэтому видео сначала начинает воспроизводиться.
  • Затем он находит обработчик videoBox.onclick. и запускает его, поэтому видео также скрывается.
Исправление проблемы с помощью stopPropagation()

Чтобы исправить это раздражающее поведение, стандартный объект события имеет функцию, называемую stopPropagation() , которая при вызове в обработчике событий объекта делает так, чтобы обработчик выполнялся, но событие не всплывало дальше по цепочке, поэтому не будут запускаться другие обработчики.

Поэтому мы можем исправить нашу текущую проблему, изменив вторую функцию-обработчик в предыдущем блоке кода:

Вы можете попробовать создать локальную копию show-video-box.html и попробовать его самостоятельно исправить или просмотреть исправленный результат в show-video-box-fixed.html (также см. исходный код здесь).

Примечание: Зачем беспокоиться как с захватом, так и с всплыванием? Что ж, в старые добрые времена, когда браузеры были менее совместимы, чем сейчас, Netscape использовал только захват событий, а Internet Explorer использовал только всплывающие события. Когда W3C решил попытаться стандартизировать поведение и достичь консенсуса, они в итоге получили эту систему, которая включала в себя и то, и другое, что реализовано в одном из современных браузеров.

Примечание: Как упоминалось выше, по умолчанию все обработчики событий регистрируются в фазе всплытия и это имеет смысл в большинстве случаев. Если вы действительно хотите зарегистрировать событие в фазе захвата, вы можете сделать это, зарегистрировав обработчик с помощью addEventListener() и установив для третьего дополнительного свойства значение true .

Делегирование события

Всплытие также позволяет нам использовать делегирование событий. Если у какого-либо родительского элемента есть множество дочерних элементов, и вы хотите, чтобы определённый код выполнялся при щелчке (событии) на каждом из дочерних элементов, можно установить обработчик событий на родительском элементе и события, происходящие на дочерних элементах будут всплывать до их родителя. При этом не нужно устанавливать обработчик событий на каждом дочернем элементе.

Хорошим примером является серия элементов списка. Если вы хотите, чтобы каждый из них, например, отображал сообщение при нажатии, вы можете установить обработчик событий click для родительского элемента <ul> и он будет всплывать в элементах списка.

Эту концепцию объясняет в своём блоге Дэвид Уолш, где приводит несколько примеров. (см. How JavaScript Event Delegation Works.)

Вывод

Это все, что вам нужно знать о веб-событиях на этом этапе. Как уже упоминалось, события не являются частью основного JavaScript — они определены в веб-интерфейсах браузера (Web API).

Кроме того, важно понимать, что различные контексты, в которых используется JavaScript, обычно имеют разные модели событий — от веб-API до других областей, таких как браузерные WebExtensions и Node.js (серверный JavaScript). Может сейчас вы не особо в этом разбираетесь, но по мере изучения веб-разработки начнёт приходить более ясное понимание тематики.

Если у вас возникли вопросы, попробуйте прочесть статью снова или обратитесь за помощью к нам.

Основы работы с объектом Event на JavaScript

Некоторые видео могут забегать вперед, тк к этому месту учебника мы прошли еще не весь ES6. Просто пропускайте такие видео, посмотрите потом.

Регулярки

  • Урок №
    Учебник
    по регулярным выражениям
  • Урок №
    Работа с регулярными
    выражениями. Глава 1.
  • Урок №
    Работа с регулярными
    выражениями. Глава 2.
  • Урок №
    Работа с регулярными
    выражениями. Глава 3.
  • Урок №
    Работа с регулярными
    выражениям. Глава 4.
  • Урок №
    Отличия
    от PHP версии

Разное

  • Урок №
    Работа
    с форматом JSON
  • Урок №
    Работа
    с куки (cookie)
  • Урок №
    Работа
    с локальным хранилищем
  • Урок №
    Анимация
    и другие эффекты

Работа с канвасом

  • Урок №
    Учебник
    по работе с canvas
  • Урок №
    Основы
    работы с canvas
  • Урок №
    Продвинутая
    работа с canvas

Практика

  • урок исключен (мало материала), по аяксу скоро будет отдельный учебник (много материала)
    Работа с
    AJAX в JavaScript —>
    Работа с
    AJAX + PHP —>

Контекст

  • Урок №
    Работа
    с контекстом и this
  • Урок №
    Продвинутая
    работа с контекстом

Drag-and-Drop

  • Урок №
    новая вкладка с new.code.mu
    Доступные события
  • Урок №
    новая вкладка с new.code.mu
    Перемещение элемента по окну
  • Урок №
    новая вкладка с new.code.mu
    Перемещение на другой элемент
  • Урок №
    новая вкладка с new.code.mu
    Объект event.dataTransfer
  • Урок №
    новая вкладка с new.code.mu
    Картинка при перетягивании
  • Урок №
    новая вкладка с new.code.mu
    Вид курсора
  • Урок №
    Введение
    в ООП в стиле ES6
  • Урок №
    Основы
    работы с ООП
  • Урок №
    Наследование
    классов в JavaScript
    Продвинутая работа
    с классами на JavaScript —>
  • Урок №
    Применение
    ООП при работе с DOM
  • Урок №
    Практика
    по ООП в JavaScript
  • Тут скоро будут еще уроки
    по функциональному и прототипному
    стилю ООП.

Практика по ООП

Ваша задача: посмотрите, попробуйте повторить.

  • Урок №
    новая вкладка ютуб
    Игра 5 точек в ряд без ООП для разминки
  • Урок №
    новая вкладка ютуб
    Игра 5 точек в ряд ООП вариант
  • Урок №
    новая вкладка ютуб
    Хранение массива в локальном хранилище (предварительная теория)
  • Урок №
    новая вкладка ютуб
    Стикеры ООП (нужны основы Drag-and-Drop, выше в учебнике есть)

Практика

  • Урок №
    новая вкладка с new.code.mu
    Тип Symbol
  • Урок №
    новая вкладка с new.code.mu
    Итераторы и генераторы

Promise ES6

  • Урок №
    новая вкладка с new.code.mu
    Функции resolve reject
  • Урок №
    новая вкладка с new.code.mu
    Метод catch
  • Урок №
    новая вкладка с new.code.mu
    Цепочки промисов
  • Урок №
    новая вкладка с new.code.mu
    Перехват ошибок
  • Урок №
    новая вкладка с new.code.mu
    Promise.all
  • Урок №
    новая вкладка с new.code.mu
    Promise.race
  • Урок №
    новая вкладка с new.code.mu
    async await
  • Урок №
    новая вкладка с new.code.mu
    Загрузка картинок

Библиотека jQuery

Тк. jQuery устаревает, объявляю эти уроки не обязательными и выношу в конец учебника (так по уровню уроки середины учебника, если что). В перспективе переедет в отдельный учебник по jq.

  • Урок №
    Учебник
    jQuery для новичков
  • Урок №
    Основы
    работы с jQuery
  • Урок №
    Манипулирование
    элементами страницы
  • Урок №
    Работа
    с набором элементов
  • Урок №
    Работа
    с событиями jQuery
  • Урок №
    Эффекты и анимация
    библиотеки jQuery
  • Урок №
    Практика на отработку
    библиотеки jQuery
  • Урок №
    Работа с
    библиотекой jQueryUI
  • Урок №
    Популярные плагины
    библиотеки jQuery

Объект Event (объект Событие) содержит в себе информацию о произошедшем событии. К примеру, если по элементу был сделан клик, мы можем узнать координаты этого клика, была ли нажата клавиша Ctrl, Alt или Shift в момент клика и так далее.

Как получить объект Event

Пусть у нас есть элемент, по клику на который выполнится функция func:

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

Это работает только для функций, привязанных к какому-либо событию.

Еще раз: если при привязывании функции к событию этой функции задать параметр — в этот параметр браузер автоматически положит объект Event. Название этого параметра будет любым — как назовете, так и будете к нему обращаться.

Координаты клика

Как уже упоминалось ранее, с помощью объекта Event можно получить координаты события, например в момент клика можно найти координаты этого клика.

Пусть в переменной event лежит объект Event. В этом случае координаты клика относительно окна браузера можно найти так: event.clientX для координаты по горизонтали и event.clientY для координаты по вертикали.

Рассмотрим пример: привяжем блоку событие onmousemove (срабатывает при движении мышкой по элементу), и будем показывать координаты курсора при движении мыши:

Поводите мышкой по элементу — вы увидите, как меняются координаты:

Кроме свойств clientX и clientY существуют также свойства pageX и pageY. Давайте посмотрим разницу между ними.

Как работают clientX и clientY: если у вас есть окно 1000 на 1000 пикселей, и мышь находится в центре, то clientX и clientY будут оба равны 500. Если вы затем прокрутите страницу по горизонтали или вертикали, не двигая курсор, то значения clientX и clientY не изменятся, так как отсчитываются относительно окна, а не документа.

Как работают pageX и pageY: если у вас есть окно 1000 на 1000 пикселей, и курсор находится в центре, то pageX и pageY будут равны 500. Если вы затем прокрутите страницу на 250 пикселей вниз, то pageY станет равным 750.

Таким образом pageX и pageY содержат координаты события с учетом прокрутки.

Тип события

Объект Event также содержит в себе тип события, к примеру для события onclick это click, для onmouseover это mouseover и так далее. Доступ к типу события можно получить так — event.type:

Элемент события

С помощью event.target можно получить элемент, в котором произошло событие. Зачем это нужно, если этот элемент содержится в this? Ответ на этот вопрос даст пример ниже.

Пусть у нас есть div, а внутри него абзац. Привяжем событие к диву, но кликнем по абзацу — в этом случае event.target будет содержать конечный тег, в котором случилось событие — то есть абзац, а не див. Убедимся в этом с помощью tagName:

Нажатые клавиши

Давайте теперь будем получать нажатые клавиши. Это актуально для тех событий, в которых происходит работа с клавиатурой, например, в onkeypress, onkeydown, onkeyup.

Для получение нажатых клавиш следует использовать свойство event.keyCode. Оно, однако, возвращает не саму клавишу, а ее код. Этот код можно преобразовать в символ с помощью метода String.fromCharCode.

Рассмотрим пример: вводите текст в инпут и по мере ввода вы будете видеть код нажатой клавиши и саму клавишу:

Введите текст в инпут:

Ctrl, Alt, Shift

Можно узнать, были ли нажаты в момент события клавиши Ctrl, Alt и Shift. Это делается с помощью свойств event.ctrlKey, event.altKey и event.shiftKey — они имеют значение true или false в зависимости от того, была ли нажата эта клавиша в момент события или нет.

В следующем примере при клике на кнопку будем выводить сообщение о том, была ли нажата одна из клавиш Ctrl, Alt или Shift:

Нажмите на кнопку, зажав при этом Ctrl, Alt или Shift:

Отмена действия

Иногда с помощью JavaScript требуется отменить действие тега по умолчанию. К примеру, по нажатию на ссылку должно произойти некоторое действие, при этом перехода по ссылке не должно произойти. Сделать это можно двумя способами — все зависит от того, как привязать событие: через атрибут, типа onclick или через JavaScript.

Если событие привязывается через атрибут — отменить действие по умолчанию можно, если в конце атрибута написать return: false, вот так: onclick=»какой-то код; return: false;».

Рассмотрим их действие на следующем примере: попробуйте перейти по ссылке или что-нибудь ввести в поле — у вас ничего не получится:

Результат выполнения кода:

До return false может быть любой JavaScript код — он выполнится, но действие пользователя будет отменено.

А вот если событие привязывается через JavaScript — то его действие можно отменить с помощью объекта Event, вот так: event.preventDefault().

Давайте сделаем так, чтобы по клику на ссылку не происходило перехода на другую страницу:

Результат выполнения кода:

Что вам делать дальше:

Приступайте к решению задач по следующей ссылке: задачи к уроку.

Когда все решите — переходите к изучению новой темы.

Учебник JavaScript

  • Урок №
    Учебник
    JavaScript для новичков
  • Урок №
    Основы
    языка JavaScript
  • Урок №
    Основы работы
    с массивами и объектами
  • Урок №
    Работа с конструкциями
    if-else и switch-case
  • Урок №
    Работа с циклами
    for и while
  • Урок №
    Работа
    с математическими функциями
  • Урок №
    Работа со строковыми
    функциями в JavaScript
  • Урок №
    Функции
    работы с массивами
  • Урок №
    Практика на комбинации
    стандартных функций
  • Урок №
    Основы работы
    с пользовательскими функциями
  • Урок №
    Приемы работы
    с флагами
  • Урок №
    Приемы работы
    с логическими значениями
  • Урок №
    Приемы работы
    с циклами
  • Урок №
    Приемы работы
    с массивами
  • Урок №
    Правильное использование
    пользовательских функций
  • Урок №
    Практика на
    пользовательские функции
  • Урок №
    Продвинутая работа
    с пользовательскими функциями

Практика

Работа с DOM

  • Урок №
    Основы
    работы с DOM
  • Урок №
    Работа
    с элементами HTML страницы
  • Урок №
    Работа
    с датами в JavaScript
  • Урок №
    Работа
    с таймерами в JavaScript
  • Урок №
    Продвинутая
    работа с событиями
  • Урок №
    Продвинутая
    работа с DOM
  • Урок №
    Работа
    с метриками
  • Урок №
    Работа
    с метриками для window
  • Урок №
    Основы работы
    с объектом Event
  • Урок №
    Продвинутая работа
    с объектом Event
  • Урок №
    Разные
    полезные темы
  • Урок №
    новая вкладка с new.code.mu
    Работа с узлами

Практика

  • Урок №
    Практика
    JavaScript для новичков
  • Урок №
    Практика
    минипроекты JavaScript
  • Урок №
    новая вкладка ютуб
    Разбор квадратного календарика
  • Урок №
    новая вкладка ютуб
    Разбор игры найди случайное число в таблице

Некоторые продвинутые вещи

  • Урок №
    Анонимные
    функции и замыкания
  • Урок №
    Некоторые продвинутые
    функции JavaScript
  • Урок №
    Нюансы
    работы с событиями
  • Урок №
    Нововведения
    в ES6 для новичков
  • Урок №
    новая вкладка с new.code.mu
    Коллекция Set
  • Урок №
    новая вкладка с new.code.mu
    Коллекция Map

Рекомендованное ES6

Некоторые видео могут забегать вперед, тк к этому месту учебника мы прошли еще не весь ES6. Просто пропускайте такие видео, посмотрите потом.

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

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

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

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

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

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 - Координаты курсора мыши при её перемещении

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

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

JavaScript - Информацию о элементе, который в данный момент создаёт событие mousemove

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

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

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

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

JavaScript - Получение некоторых свойств KeyboardEvent при наступлении события keyup

Отличие target от currentTarget

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

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

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

При клике на 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 :

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

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

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

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

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

JavaScript - Использование target и relatedTarget для событий mouseover и mouseout

Задачи

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

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

Задача по JavaScript - Удалить элемент из DOM при клике на нем

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

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

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

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

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *