minor
This commit is contained in:
parent
703a4f4678
commit
fc66b43ce3
1 changed files with 17 additions and 19 deletions
|
@ -15,7 +15,7 @@ If we handle an event in JavaScript, often we don't want browser actions. Fortun
|
||||||
There are two ways to tell the browser we don't want it to act:
|
There are two ways to tell the browser we don't want it to act:
|
||||||
|
|
||||||
- The main way is to use the `event` object. There's a method `event.preventDefault()`.
|
- The main way is to use the `event` object. There's a method `event.preventDefault()`.
|
||||||
- If the handler is assigned using `on<event>` (not by `addEventListener`), then we can just return `false` from it.
|
- If the handler is assigned using `on<event>` (not by `addEventListener`), then we can also return `false` from it.
|
||||||
|
|
||||||
In the example below a click to links doesn't lead to URL change:
|
In the example below a click to links doesn't lead to URL change:
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ The value returned by an event handler is usually ignored.
|
||||||
|
|
||||||
The only exception -- is `return false` from a handler assigned using `on<event>`.
|
The only exception -- is `return false` from a handler assigned using `on<event>`.
|
||||||
|
|
||||||
In all other cases, the return is not needed and it's not processed anyhow.
|
In all other cases, `return` is not needed and it's not processed anyhow.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Example: the menu
|
### Example: the menu
|
||||||
|
@ -71,20 +71,16 @@ menu.onclick = function(event) {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
If we omit `return false`, then after our code executes the browser will do its "default action" -- following to the URL in `href`.
|
If we omit `return false`, then after our code executes the browser will do its "default action" -- navigating to the URL in `href`. And we don't need that here, as we're handling the click by ourselves.
|
||||||
|
|
||||||
By the way, using event delegation here makes our menu flexible. We can add nested lists and style them using CSS to "slide down".
|
By the way, using event delegation here makes our menu very flexible. We can add nested lists and style them using CSS to "slide down".
|
||||||
|
|
||||||
|
|
||||||
## Prevent further events
|
|
||||||
|
|
||||||
|
````smart header="Follow-up events"
|
||||||
Certain events flow one into another. If we prevent the first event, there will be no second.
|
Certain events flow one into another. If we prevent the first event, there will be no second.
|
||||||
|
|
||||||
For instance, `mousedown` on an `<input>` field leads to focusing in it, and the `focus` event. If we prevent the `mousedown` event, there's no focus.
|
For instance, `mousedown` on an `<input>` field leads to focusing in it, and the `focus` event. If we prevent the `mousedown` event, there's no focus.
|
||||||
|
|
||||||
Try to click on the first `<input>` below -- the `focus` event happens. That's normal.
|
Try to click on the first `<input>` below -- the `focus` event happens. But if you click the second one, there's no focus.
|
||||||
|
|
||||||
But if you click the second one, there's no focus.
|
|
||||||
|
|
||||||
```html run autorun
|
```html run autorun
|
||||||
<input value="Focus works" onfocus="this.value=''">
|
<input value="Focus works" onfocus="this.value=''">
|
||||||
|
@ -92,6 +88,7 @@ But if you click the second one, there's no focus.
|
||||||
```
|
```
|
||||||
|
|
||||||
That's because the browser action is canceled on `mousedown`. The focusing is still possible if we use another way to enter the input. For instance, the `key:Tab` key to switch from the 1st input into the 2nd. But not with the mouse click any more.
|
That's because the browser action is canceled on `mousedown`. The focusing is still possible if we use another way to enter the input. For instance, the `key:Tab` key to switch from the 1st input into the 2nd. But not with the mouse click any more.
|
||||||
|
````
|
||||||
|
|
||||||
## The "passive" handler option
|
## The "passive" handler option
|
||||||
|
|
||||||
|
@ -116,21 +113,23 @@ There's an interesting use case for it.
|
||||||
|
|
||||||
You remember in the chapter <info:bubbling-and-capturing> we talked about `event.stopPropagation()` and why stopping bubbling is bad?
|
You remember in the chapter <info:bubbling-and-capturing> we talked about `event.stopPropagation()` and why stopping bubbling is bad?
|
||||||
|
|
||||||
Sometimes we can use `event.defaultPrevented` instead.
|
Sometimes we can use `event.defaultPrevented` instead, to signal other event handlers that the event was handled.
|
||||||
|
|
||||||
Let's see a practical example where stopping the bubbling looks necessary, but actually we can do well without it.
|
Let's see a practical example.
|
||||||
|
|
||||||
By default the browser on `contextmenu` event (right mouse click) shows a context menu with standard options. We can prevent it and show our own, like this:
|
By default the browser on `contextmenu` event (right mouse click) shows a context menu with standard options. We can prevent it and show our own, like this:
|
||||||
|
|
||||||
```html autorun height=50 no-beautify run
|
```html autorun height=50 no-beautify run
|
||||||
<button>Right-click for browser context menu</button>
|
<button>Right-click shows browser context menu</button>
|
||||||
|
|
||||||
<button *!*oncontextmenu="alert('Draw our menu'); return false"*/!*>
|
<button *!*oncontextmenu="alert('Draw our menu'); return false"*/!*>
|
||||||
Right-click for our context menu
|
Right-click shows our context menu
|
||||||
</button>
|
</button>
|
||||||
```
|
```
|
||||||
|
|
||||||
Now let's say we want to implement our own document-wide context menu, with our options. And inside the document we may have other elements with their own context menus:
|
Now, in addition to that context menu we'd like to implement document-wide context menu.
|
||||||
|
|
||||||
|
Upon right click, the closest context menu should show up.
|
||||||
|
|
||||||
```html autorun height=80 no-beautify run
|
```html autorun height=80 no-beautify run
|
||||||
<p>Right-click here for the document context menu</p>
|
<p>Right-click here for the document context menu</p>
|
||||||
|
@ -151,7 +150,7 @@ Now let's say we want to implement our own document-wide context menu, with our
|
||||||
|
|
||||||
The problem is that when we click on `elem`, we get two menus: the button-level and (the event bubbles up) the document-level menu.
|
The problem is that when we click on `elem`, we get two menus: the button-level and (the event bubbles up) the document-level menu.
|
||||||
|
|
||||||
How to fix it? One of solutions is to think like: "We fully handle the event in the button handler, let's stop it" and use `event.stopPropagation()`:
|
How to fix it? One of solutions is to think like: "When we handle right-click in the button handler, let's stop its bubbling" and use `event.stopPropagation()`:
|
||||||
|
|
||||||
```html autorun height=80 no-beautify run
|
```html autorun height=80 no-beautify run
|
||||||
<p>Right-click for the document menu</p>
|
<p>Right-click for the document menu</p>
|
||||||
|
@ -179,7 +178,7 @@ An alternative solution would be to check in the `document` handler if the defau
|
||||||
|
|
||||||
|
|
||||||
```html autorun height=80 no-beautify run
|
```html autorun height=80 no-beautify run
|
||||||
<p>Right-click for the document menu (fixed with event.defaultPrevented)</p>
|
<p>Right-click for the document menu (added a check for event.defaultPrevented)</p>
|
||||||
<button id="elem">Right-click for the button menu</button>
|
<button id="elem">Right-click for the button menu</button>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -206,7 +205,7 @@ As we can clearly see, `event.stopPropagation()` and `event.preventDefault()` (a
|
||||||
```
|
```
|
||||||
|
|
||||||
```smart header="Nested context menus architecture"
|
```smart header="Nested context menus architecture"
|
||||||
There are also alternative ways to implement nested context menus. One of them is to have a special global object with a method that handles `document.oncontextmenu`, and also methods that allow to store various "lower-level" handlers in it.
|
There are also alternative ways to implement nested context menus. One of them is to have a single global object with a handler for `document.oncontextmenu`, and also methods that allow to store other handlers in it.
|
||||||
|
|
||||||
The object will catch any right-click, look through stored handlers and run the appropriate one.
|
The object will catch any right-click, look through stored handlers and run the appropriate one.
|
||||||
|
|
||||||
|
@ -220,7 +219,6 @@ There are many default browser actions:
|
||||||
- `mousedown` -- starts the selection (move the mouse to select).
|
- `mousedown` -- starts the selection (move the mouse to select).
|
||||||
- `click` on `<input type="checkbox">` -- checks/unchecks the `input`.
|
- `click` on `<input type="checkbox">` -- checks/unchecks the `input`.
|
||||||
- `submit` -- clicking an `<input type="submit">` or hitting `key:Enter` inside a form field causes this event to happen, and the browser submits the form after it.
|
- `submit` -- clicking an `<input type="submit">` or hitting `key:Enter` inside a form field causes this event to happen, and the browser submits the form after it.
|
||||||
- `wheel` -- rolling a mouse wheel event has scrolling as the default action.
|
|
||||||
- `keydown` -- pressing a key may lead to adding a character into a field, or other actions.
|
- `keydown` -- pressing a key may lead to adding a character into a field, or other actions.
|
||||||
- `contextmenu` -- the event happens on a right-click, the action is to show the browser context menu.
|
- `contextmenu` -- the event happens on a right-click, the action is to show the browser context menu.
|
||||||
- ...there are more...
|
- ...there are more...
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue