Как отследить нажатие на кнопку js
Перейти к содержимому

Как отследить нажатие на кнопку js

  • автор:

Mouse events

In this chapter we’ll get into more details about mouse events and their properties.

Please note: such events may come not only from “mouse devices”, but are also from other devices, such as phones and tablets, where they are emulated for compatibility.

Mouse event types

We’ve already seen some of these events:

mousedown/mouseup Mouse button is clicked/released over an element. mouseover/mouseout Mouse pointer comes over/out from an element. mousemove Every mouse move over an element triggers that event. click Triggers after mousedown and then mouseup over the same element if the left mouse button was used. dblclick Triggers after two clicks on the same element within a short timeframe. Rarely used nowadays. contextmenu Triggers when the right mouse button is pressed. There are other ways to open a context menu, e.g. using a special keyboard key, it triggers in that case also, so it’s not exactly the mouse event.

…There are several other events too, we’ll cover them later.

Events order

As you can see from the list above, a user action may trigger multiple events.

For instance, a left-button click first triggers mousedown , when the button is pressed, then mouseup and click when it’s released.

In cases when a single action initiates multiple events, their order is fixed. That is, the handlers are called in the order mousedown → mouseup → click .

Click the button below and you’ll see the events. Try double-click too.

On the teststand below, all mouse events are logged, and if there is more than a 1 second delay between them, they are separated by a horizontal rule.

Also, we can see the button property that allows us to detect the mouse button; it’s explained below.

Mouse button

Click-related events always have the button property, which allows to get the exact mouse button.

We usually don’t use it for click and contextmenu events, because the former happens only on left-click, and the latter – only on right-click.

On the other hand, mousedown and mouseup handlers may need event.button , because these events trigger on any button, so button allows to distinguish between “right-mousedown” and “left-mousedown”.

The possible values of event.button are:

Button state event.button
Left button (primary) 0
Middle button (auxiliary) 1
Right button (secondary) 2
X1 button (back) 3
X2 button (forward) 4

Most mouse devices only have the left and right buttons, so possible values are 0 or 2 . Touch devices also generate similar events when one taps on them.

Also there’s event.buttons property that has all currently pressed buttons as an integer, one bit per button. In practice this property is very rarely used, you can find details at MDN if you ever need it.

Old code may use event.which property that’s an old non-standard way of getting a button, with possible values:

  • event.which == 1 – left button,
  • event.which == 2 – middle button,
  • event.which == 3 – right button.

As of now, event.which is deprecated, we shouldn’t use it.

Modifiers: shift, alt, ctrl and meta

All mouse events include the information about pressed modifier keys.

  • shiftKey : Shift
  • altKey : Alt (or Opt for Mac)
  • ctrlKey : Ctrl
  • metaKey : Cmd for Mac

They are true if the corresponding key was pressed during the event.

For instance, the button below only works on Alt + Shift +click:

On Windows and Linux there are modifier keys Alt , Shift and Ctrl . On Mac there’s one more: Cmd , corresponding to the property metaKey .

In most applications, when Windows/Linux uses Ctrl , on Mac Cmd is used.

That is: where a Windows user presses Ctrl + Enter or Ctrl + A , a Mac user would press Cmd + Enter or Cmd + A , and so on.

So if we want to support combinations like Ctrl +click, then for Mac it makes sense to use Cmd +click. That’s more comfortable for Mac users.

Even if we’d like to force Mac users to Ctrl +click – that’s kind of difficult. The problem is: a left-click with Ctrl is interpreted as a right-click on MacOS, and it generates the contextmenu event, not click like Windows/Linux.

So if we want users of all operating systems to feel comfortable, then together with ctrlKey we should check metaKey .

For JS-code it means that we should check if (event.ctrlKey || event.metaKey) .

Keyboard combinations are good as an addition to the workflow. So that if the visitor uses a keyboard – they work.

But if their device doesn’t have it – then there should be a way to live without modifier keys.

Coordinates: clientX/Y, pageX/Y

All mouse events provide coordinates in two flavours:

  1. Window-relative: clientX and clientY .
  2. Document-relative: pageX and pageY .

We already covered the difference between them in the chapter Coordinates.

In short, document-relative coordinates pageX/Y are counted from the left-upper corner of the document, and do not change when the page is scrolled, while clientX/Y are counted from the current window left-upper corner. When the page is scrolled, they change.

For instance, if we have a window of the size 500×500, and the mouse is in the left-upper corner, then clientX and clientY are 0 , no matter how the page is scrolled.

And if the mouse is in the center, then clientX and clientY are 250 , no matter what place in the document it is. They are similar to position:fixed in that aspect.

Move the mouse over the input field to see clientX/clientY (the example is in the iframe , so coordinates are relative to that iframe ):

Preventing selection on mousedown

Double mouse click has a side effect that may be disturbing in some interfaces: it selects text.

For instance, double-clicking on the text below selects it in addition to our handler:

If one presses the left mouse button and, without releasing it, moves the mouse, that also makes the selection, often unwanted.

There are multiple ways to prevent the selection, that you can read in the chapter Selection and Range.

In this particular case the most reasonable way is to prevent the browser action on mousedown . It prevents both these selections:

Now the bold element is not selected on double clicks, and pressing the left button on it won’t start the selection.

Please note: the text inside it is still selectable. However, the selection should start not on the text itself, but before or after it. Usually that’s fine for users.

If we want to disable selection to protect our page content from copy-pasting, then we can use another event: oncopy .

If you try to copy a piece of text in the <div> , that won’t work, because the default action oncopy is prevented.

Surely the user has access to HTML-source of the page, and can take the content from there, but not everyone knows how to do it.

Summary

Mouse events have the following properties:

Modifier keys ( true if pressed): altKey , ctrlKey , shiftKey and metaKey (Mac).

  • If you want to handle Ctrl , then don’t forget Mac users, they usually use Cmd , so it’s better to check if (e.metaKey || e.ctrlKey) .

Window-relative coordinates: clientX/clientY .

Document-relative coordinates: pageX/pageY .

The default browser action of mousedown is text selection, if it’s not good for the interface, then it should be prevented.

In the next chapter we’ll see more details about events that follow pointer movement and how to track element changes under it.

addEventListener()

Метод addEventListener — это самый функциональный способ позволяющий добавить обработчик события к указанному элементу и запустить выполнение программы при совершении заданного действия. Получить информацию о сигналах браузера можно из Document (DOM), Element , Window и других объектов поддерживающих события.

addEventListener() является одних из трёх способом прослушивать события, наряду с добавление атрибута к тегам в HTML и обращения к свойствам объекта напрямую.

addEventListener() имеет важное преимущество перед остальными способами, метод позволяет навесить несколько обработчиков на одно событие. Это происходит из-за того, что у объекта только одно свойство, например с именем onclick (клик) или mousemove (движение мыши) и если обратиться к одному из них напрямую несколько раз, второй обработчик перезапишет первый.

В примере выше, как раз можно наблюдать описанный эффект — модальное окно с Да будет так! появится, а вот Терпение и труд всё перетрут нет.

Также отследить некоторые события можно только с помощью addEventListener() , например навесить обработчик на DOMContentLoaded по другому не получиться.

Синтаксис

element — объект, действие по которому отслеживаем.

eventType — тип события, которое мы хотим отследить: клик, прокрутка мыши, нажатие клавиши и т.д. Написание чувствительно к регистру: click правильно, Click или CLICK неправильно.

handler — имя функции или сама функция, которая будет выполнена после наступления события.

options — необязательный объект со свойствами, внутри которого доступны следующие параметры:

  • capture : значение записывается в формате true или false и задает этап, на котором будет обработано событие. По умолчанию false — на этапе всплытия, true — на этапе погружения (перехват). Если вместо options задать булево значение — это будет равносильно
  • once : значение типа boolean , по умолчанию false , если true тогда обработчик будет удален после выполнения.
  • passive : по умолчанию false , если true обработчик никогда не вызовет preventDefault() , взамен этого будет сгенерировано предупреждение в console.

При клике на кнопку мы получим модальное окно с сообщением, если кликнуть второй раз ничего не произойдет, так как свойство once равно true — после события обработчик удаляется.

removeEventListener()

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

В этом случае, если поменять текст на кнопке обработчик удален не будет.

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

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

Популярные события

Рассмотрим события, которые отслеживаются чаще других:

click — клик левой кнопкой мыши по элементу, на сенсорных устройствах это касание;

contextmenu — клик на элемент правой кнопкой мыши — вызов контекстного меню;

mouseover / mouseout — наведение на элемент курсора мыши / курсор покидает элемент;

mousemove — движение мыши;

keydown / keyup — клавиша нажата / клавиша отпущена;

DOMContentLoaded — весь HTML загружен, а DOM-дерево построено.

Для того, чтобы посмотреть все возможные события для DOM-элемента, нажмите правой кнопкой на страницу, далее Просмотреть код, выберите элемент на странице, а далее кликните на Свойства (Properties). В фильтре наберите on, все что начинает на on являются событиями.

свойства элемента в браузере

Как добавить обработчик на множество элементом

addEventListener и forEach

В данном примере мы получили все элементы с классом myChoice в объект через querySelectorAll() , а потом с помощью forEach() перебором назначили обработчик события на все кнопки.

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

Вторым и более удачным способом отслеживать события на множестве элементов это делегирование.

В этом примере мы назначаем обработчик для родителя в котором содержатся интересующие нас элементы. Далее отслеживаем с помощью event.target.closest(‘.hideText’) было ли взаимодействие с тегом с классом .hideText и если это так удаляем оттуда класс, который делает текст белым.

Всплытие и погружение

Всплытие — это когда обработчик сначала срабатывает на элементе с которым произошло взаимодействие, затем событие обрабатывается на его родителе и далее выше по цепочке.

Погружение — при взаимодействии с объектом, который находится ниже чем элемент со свойством capture: true , сначала событие будет обработано на последнем, далее обработчик сработает на всех потомках и только потом на всех родителях.

Для того, чтобы понять тему потренируйтесь на примере, наблюдая последовательность выполнения действий при клике на различные элементы. Результат отслеживайте в console.

Пример с квадратами

Получаем доступ к элементу через this

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

Итого

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

Удалить обработчик события после использования можно двумя способами: с помощью свойства once со значением true или метода removeEventListener() .

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

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

Element: click event

An element receives a click event when a pointing device button (such as a mouse’s primary mouse button) is both pressed and released while the pointer is located inside the element.

If the button is pressed on one element and the pointer is moved outside the element before the button is released, the event is fired on the most specific ancestor element that contained both elements.

click fires after both the mousedown and mouseup events have fired, in that order.

Syntax

Use the event name in methods like addEventListener() , or set an event handler property.

Event type

Event properties

This interface also inherits properties of its parents, UIEvent and Event .

Returns true if the alt key was down when the mouse event was fired.

The button number that was pressed (if applicable) when the mouse event was fired.

The buttons being pressed (if any) when the mouse event was fired.

The X coordinate of the mouse pointer in local (DOM content) coordinates.

The Y coordinate of the mouse pointer in local (DOM content) coordinates.

Returns true if the control key was down when the mouse event was fired.

Returns the horizontal coordinate of the event relative to the current layer.

Returns the vertical coordinate of the event relative to the current layer.

Returns true if the meta key was down when the mouse event was fired.

The X coordinate of the mouse pointer relative to the position of the last mousemove event.

The Y coordinate of the mouse pointer relative to the position of the last mousemove event.

The X coordinate of the mouse pointer relative to the position of the padding edge of the target node.

The Y coordinate of the mouse pointer relative to the position of the padding edge of the target node.

The X coordinate of the mouse pointer relative to the whole document.

The Y coordinate of the mouse pointer relative to the whole document.

The secondary target for the event, if there is one.

The X coordinate of the mouse pointer in global (screen) coordinates.

The Y coordinate of the mouse pointer in global (screen) coordinates.

Returns true if the shift key was down when the mouse event was fired.

The amount of pressure applied to a touch or tablet device when generating the event; this value ranges between 0.0 (minimum pressure) and 1.0 (maximum pressure). Instead of using this deprecated (and non-standard) property, you should use PointerEvent and look at its pressure property.

The type of device that generated the event (one of the MOZ_SOURCE_* constants). This lets you, for example, determine whether a mouse event was generated by an actual mouse or by a touch event (which might affect the degree of accuracy with which you interpret the coordinates associated with the event).

The amount of pressure applied when clicking.

Usage notes

The MouseEvent object passed into the event handler for click has its detail property set to the number of times the target was clicked. In other words, detail will be 2 for a double-click, 3 for triple-click, and so forth. This counter resets after a short interval without any clicks occurring; the specifics of how long that interval is may vary from browser to browser and across platforms. The interval is also likely to be affected by user preferences; for example, accessibility options may extend this interval to make it easier to perform multiple clicks with adaptive interfaces.

Examples

This example displays the number of consecutive clicks on a <button> .

Name already in use

javascript-tutorial-ru / 2-ui / 3-event-details / 1-mouse-clicks / article.md

  • Go to file T
  • Go to line L
  • Copy path
  • Copy permalink
  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents

Copy raw contents

Copy raw contents

Мышь: клики, кнопка, координаты

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

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

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

mousedown : Кнопка мыши нажата над элементом.

mouseup : Кнопка мыши отпущена над элементом.

mouseover : Мышь появилась над элементом.

mouseout : Мышь ушла с элемента.

mousemove : Каждое движение мыши над элементом генерирует это событие.

click : Вызывается при клике мышью, то есть при mousedown , а затем mouseup на одном элементе

contextmenu : Вызывается при клике правой кнопкой мыши на элементе.

dblclick : Вызывается при двойном клике по элементу.

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

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

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

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

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

Каждое событие обрабатывается независимо.

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

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

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

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

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

Возможны следующие значения:

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

Это свойство не поддерживается IE8-, но его можно получить способом, описанным в конце главы.

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

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

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

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

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

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

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

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

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

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

В большинстве случаев там, где под Windows/Linux используется key:Ctrl , на Mac используется key:Cmd . Там, где пользователь Windows нажимает key:Ctrl+Enter или key:Ctrl+A , пользователь Mac нажмёт key:Cmd+Enter или key:Cmd+A , и так далее, почти всегда key:Cmd вместо key:Ctrl .

Поэтому, если мы хотим поддерживать сочетание key:Ctrl +click или другие подобные, то под Mac имеет смысл использовать key:Cmd +click. Пользователям Mac это будет гораздо комфортнее.

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

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

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

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

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

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

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

В IE8- этих свойств нет, но можно получить их способом, описанным в конце главы.

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

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

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

Свойства pageX/pageY [#fixPageXY]

В IE до версии 9 не поддерживаются свойства pageX/pageY , но их можно получить, прибавив к clientX/clientY величину прокрутки страницы.

Более подробно о её вычислении вы можете прочитать в разделе прокрутка страницы.

Мы же здесь приведем готовый вариант, который позволяет нам получить pageX/pageY для старых и совсем старых IE:

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

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