События мыши: клики, кнопка, координаты

События мыши: клики, кнопка, координаты

Здравствуйте! В этой статье в продолжении темы «События в JavaScript»  я хотел бы  мы глубже разобраться со списком событий мыши, рассмотреть их общие свойства, а также те события, которые связаны с кликом мыши.  Ведь когда пользователь кликает на каком то элементе, то на самом деле происходят 2 события mousedown и mouseup.  Ну и также еще имеется ряд нюансов при работе с мышью.

события мыши: клики, координаты

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

Условно события мыши  можно разделить  на 2 типа: «простые» и «комплексные».

Простые события

mousedown
Кнопка мыши нажата над элементом, но еще не отпущена.
mouseup
Кнопка мыши уже  отпущена над элементом.
mouseover
Пользователь навел мышью  на элемент.
mouseout
Мышь вышла за пределы элемента.
mousemove
Происходит, когда пользователь  водит мышью на элементе

Комплексные события

click
Происходит  при клике мышью, то есть это  mousedown  + mouseup на одном элементе
contextmenu
Происходит при клике правой кнопкой мыши при этом вызывается контекстное меню.
dblclick
Происходит при двойном щелчке на элементе

Как видно комплексные события состоят из двух и более простых событий.

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

Одно действие может  порождать несколько событий.

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

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

Например, при клике события mouseup + click возникают одновременно, но обрабатываются последовательно. Сначала полностью завершается обработка mouseup, затем запускается click.

Получение информации о кнопке: which

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

Для получения кнопки мыши в объекте event есть  специальное свойство which.

Читайте также  Делегирование событий в JavaScript

На практике оно  конечно используется редко, т.к. обычно обработчик вешается либо onclick – только на левую кнопку, либо oncontextmenu – только на правую.

Возможны такие значения:

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

Правый клик: oncontextmenu

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

<div>Правый клик на этой кнопке выведет "Клик".</div>
<button oncontextmenu="alert('Клик!');">Правый клик сюда</button>

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

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

В примере ниже встроенное меню показано не будет:

<button oncontextmenu="alert('Клик!');return false">Правый клик сюда</button>

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

Во всех событиях мыши присутствует также и  информация о нажатых клавишах-модификаторах. Это клавиши Shift, Ctrl, Alt.

Собственно  свойства:

  • shiftKey
  • altKey
  • ctrlKey
  • metaKey (для Mac)

Например, кнопка  сработает только на Alt+Shift+Клик:

<button>Alt+Shift+Кликни меня!</button>
<script>
  document.body.children[0].onclick = function(e) {
    if (!e.altKey || !e.shiftKey) return;
    alert( 'Ура!' );
  }
</script>

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

В случаях, где под Windows/Linux используется Ctrl, на Mac используется Cmd. Там, где пользователь Windows нажимает Ctrl+F2 или Ctrl+B, пользователь Mac нажмёт Cmd+F2 или Cmd+B.

Более того, даже если бы вы захотели заставить пользователей Mac использовать именно Ctrl+click – это было бы весьма затруднительно. Все дело в том, что обычный клик с зажатым Ctrl под Mac работает как правый клик и генерирует событие oncontextmenu, а вовсе не onclick, как под Windows/Linux.

Читайте также  События мыши: отмена выделения

Решение состоит втом, чтобы пользователи обоих операционных систем работали с комфортом, в паре с ctrlKey нужно обязательно использовать metaKey.

Ну а в коде это означает, что для удобства пользователей Mac вам нужно проверять if (event.ctrlKey || event.metaKey).

Координаты в окне: clientX/Y

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

Пара свойств clientX/clientY  будет содержать  координаты курсора относительно текущего окна.

При этом, например, если ваше окно размером 300×300, а мышь находится в центре, тогда и clientX и clientY будут равны 150.

И вы можете  как угодно прокручивать страницу, но если при этом  не двигать  мышь, то  соотвественно координаты курсора clientX/clientY не изменятся, потому что они считаются относительно окна, а не документа.

Вот пример обработки координат курсора:

<input onmousemove="this.value = event.clientX+':'+event.clientY">

В той же системе координат работает и функция elem.getBoundingClientRect(), возвращающая координаты элемента, а также и position:fixed.

Относительно документа: pageX/Y

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

Так как эти координаты – относительно левого-верхнего узла документа, а не окна, то они будут  учитывать прокрутку документа. Если прокрутить страницу, а мышь при этом  не трогать, то координаты курсора pageX/pageY изменятся на естественно на величину прокрутки, они будут  привязаны к конкретной точке в документе.

Пример считывания  координат курсора относительно документа.

<input onmousemove="this.value = event.pageX+':'+event.pageY">

В той же системе координат работает position:absolute, если элемент позиционируется относительно документа.

Некоторые браузеры поддерживают и свойства event.x/y, event.layerX/layerY.

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

Итоги

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

  • Кнопка мыши: which
  • Элемент,  который вызвал событие: target
  • Координаты, относительно окна: clientX/clientY
  • Координаты, относительно документа: pageX/pageY
  • Если зажата спец. клавиша (shift, alt, ctrl), то стоит соответствующее свойство: altKey, ctrlKey, shiftKey или metaKey (Mac).
  • Для поддержки Ctrl+click  надо проверить if (e.metaKey || e.ctrlKey), чтобы пользователи Mac тоже были довольны.
Читайте также  Объект события Event

Задачи

Список с выделением

Эта задача состоит из 2-х частей.

  1. Сделайте список, элементы которого можно выделять кликом.
  2. Добавьте мульти-выделение. Если клик с нажатым Ctrl (Cmd под Mac), то элемент должен  добавляться-удаляться из выделенных.

Дерево: проверка клика на заголовке

Есть кликабельное JavaScript-дерево UL/LI .

<ul>
  <li>Млекопитающие
    <ul>
      <li>Коровы</li>
      <li>Ослы</li>
      <li>Собаки</li>
      <li>Тигры</li>
    </ul>
  </li>
</ul>

При клике на заголовке его список его детей скрывается-раскрывается.

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

Как скрывать/раскрывать детей только при клике на заголовок?

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Плюсануть
Поделиться

Об авторе

admin administrator

Сообщить об опечатке

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