# Mouse events basics 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 can split mouse events into two categories: "simple" and "complex" ### Simple events The most used simple events are: `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. ...There are several other event types too, we'll cover them later. ### Complex events `click` : Triggers after `mousedown` and then `mouseup` over the same element if the left mouse button was used. `contextmenu` : Triggers after `mousedown` if the right mouse button was used. `dblclick` : Triggers after a double click over an element. Complex events are made of simple ones, so in theory we could live without them. But they exist, and that's good, because they are convenient. ### Events order An action may trigger multiple events. For instance, a 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 are more than 1 second delay between them, then they are separated by a horizontal ruler. Also we can see the `which` property that allows to detect the mouse button.
``` ## Getting the button: which Click-related events always have the `which` property, which allows to get the exact mouse button. It is not used for `click` and `contextmenu` events, because the former happens only on left-click, and the latter -- only on right-click. But if we track `mousedown` and `mouseup`, then we need it, because these events trigger on any button, so `which` allows to distinguish between "right-mousedown" and "left-mousedown". There are the three possible values: - `event.which == 1` -- the left button - `event.which == 2` - the middle button - `event.which == 3` - the right button The middle button is somewhat exotic right now and is very rarely used. ## 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 operational 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 has a keyboard -- it works. And if their device doesn't have it -- then there should be another way to do the same. ``` ## Coordinates: clientX/Y, pageX/Y All mouse events have coordinates in two flavours: 1. Window-relative: `clientX` and `clientY`. 2. Document-relative: `pageX` and `pageY`. For instance, if we have a window of the size 500x500, and the mouse is in the left-upper corner, then `clientX` and `clientY` are `0`. And if the mouse is in the center, then `clientX` and `clientY` are `250`, no matter what place in the document it is, how far the document was scrolled. They are similar to `position:fixed`. ````online Move the mouse over the input field to see `clientX/clientY` (the example is in the `iframe`, so coordinates are relative to that `iframe`): ```html autorun height=50 ``` ```` Document-relative coordinates `pageX`, `pageY` are counted from the left-upper corner of the document, not the window. You can read more about coordinates in the chapter