Здравствуйте! В этой статье в продолжении темы «События в JavaScript» я хотел бы мы глубже разобраться со списком событий мыши, рассмотреть их общие свойства, а также те события, которые связаны с кликом мыши. Ведь когда пользователь кликает на каком то элементе, то на самом деле происходят 2 события mousedown и mouseup. Ну и также еще имеется ряд нюансов при работе с мышью.
Условно события мыши можно разделить на 2 типа: «простые» и «комплексные».
Как видно комплексные события состоят из двух и более простых событий.
Одно действие может порождать несколько событий.
Например, клик мышью вызовет сначала mousedown при нажатии, а затем mouseup и click при отпускании кнопки.
В случаях, когда одно действие генерирует много событий, их порядок, как правило фиксирован. Таким образом обработчики вызовутся в следующем порядке mousedown → mouseup → click.
Например, при клике события mouseup + click возникают одновременно, но обрабатываются последовательно. Сначала полностью завершается обработка mouseup, затем запускается click.
При обработке событий, связанных с кликами мыши, иногда бывает важно знать, какая кнопка мыши нажата.
Для получения кнопки мыши в объекте event есть специальное свойство which.
На практике оно конечно используется редко, т.к. обычно обработчик вешается либо onclick – только на левую кнопку, либо oncontextmenu – только на правую.
Возможны такие значения:
Это событие будет срабатывать при клике правой кнопкой мыши:
<div>Правый клик на этой кнопке выведет "Клик".</div> <button oncontextmenu="alert('Клик!');">Правый клик сюда</button>
При клике на кнопку выше после обработчика oncontextmenu будет показано обычное контекстное меню, которое браузер всегда показывает при клике данной кнопкой.
Если вы не хотите, чтобы показывалось контекстное меню по умолчанию, а хотите например показать своё, специфичное для вашего приложения, то можно отменить действие по умолчанию.
В примере ниже встроенное меню показано не будет:
<button oncontextmenu="alert('Клик!');return false">Правый клик сюда</button>
Во всех событиях мыши присутствует также и информация о нажатых клавишах-модификаторах. Это клавиши Shift, Ctrl, Alt.
Собственно свойства:
Например, кнопка сработает только на 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/clientY будет содержать координаты курсора относительно текущего окна.
При этом, например, если ваше окно размером 300×300, а мышь находится в центре, тогда и clientX и clientY будут равны 150.
И вы можете как угодно прокручивать страницу, но если при этом не двигать мышь, то соотвественно координаты курсора clientX/clientY не изменятся, потому что они считаются относительно окна, а не документа.
Вот пример обработки координат курсора:
<input onmousemove="this.value = event.clientX+':'+event.clientY">
В той же системе координат работает и функция elem.getBoundingClientRect(), возвращающая координаты элемента, а также и position:fixed.
Координаты курсора относительно документа находятся в свойствах pageX/pageY.
Так как эти координаты – относительно левого-верхнего узла документа, а не окна, то они будут учитывать прокрутку документа. Если прокрутить страницу, а мышь при этом не трогать, то координаты курсора pageX/pageY изменятся на естественно на величину прокрутки, они будут привязаны к конкретной точке в документе.
Пример считывания координат курсора относительно документа.
<input onmousemove="this.value = event.pageX+':'+event.pageY">
В той же системе координат работает position:absolute, если элемент позиционируется относительно документа.
Некоторые браузеры поддерживают и свойства event.x/y, event.layerX/layerY.
Эти свойства устарели, они нестандартные и не добавляют ничего к описанным выше. Использовать их не стоит.
События мыши имеют следующие свойства:
Эта задача состоит из 2-х частей.
Есть кликабельное JavaScript-дерево UL/LI .
<ul> <li>Млекопитающие <ul> <li>Коровы</li> <li>Ослы</li> <li>Собаки</li> <li>Тигры</li> </ul> </li> </ul>
При клике на заголовке его список его детей скрывается-раскрывается.
Однако, проблема в том, что скрытие-раскрытие происходит даже при клике вне заголовка, на пустом пространстве справа от него.
Как скрывать/раскрывать детей только при клике на заголовок?
Об авторе