# 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`. ```online 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 ruler. Also we can see the `button` property that allows 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. From the other hand, `mousedown` and `mouseup` handlers we 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](mdn:/api/MouseEvent/buttons) if you ever need it. ```warn header="The outdated `event.which`" 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. Event properties: - `shiftKey`: `key:Shift` - `altKey`: `key:Alt` (or `key:Opt` for Mac) - `ctrlKey`: `key:Ctrl` - `metaKey`: `key:Cmd` for Mac They are `true` if the corresponding key was pressed during the event. For instance, the button below only works on `key:Alt+Shift`+click: ```html autorun height=60 ``` ```warn header="Attention: on Mac it's usually `Cmd` instead of `Ctrl`" On Windows and Linux there are modifier keys `key:Alt`, `key:Shift` and `key:Ctrl`. On Mac there's one more: `key:Cmd`, corresponding to the property `metaKey`. In most applications, when Windows/Linux uses `key:Ctrl`, on Mac `key:Cmd` is used. That is: where a Windows user presses `key:Ctrl+Enter` or `key:Ctrl+A`, a Mac user would press `key:Cmd+Enter` or `key:Cmd+A`, and so on. So if we want to support combinations like `key:Ctrl`+click, then for Mac it makes sense to use `key:Cmd`+click. That's more comfortable for Mac users. Even if we'd like to force Mac users to `key:Ctrl`+click -- that's kind of difficult. The problem is: a left-click with `key: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)`. ``` ```warn header="There are also mobile devices" 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