Skip to content

Commit ba2b7b0

Browse files
committed
minor
1 parent 405032e commit ba2b7b0

File tree

1 file changed

+39
-40
lines changed
  • 2-ui/2-events/01-introduction-browser-events

1 file changed

+39
-40
lines changed

2-ui/2-events/01-introduction-browser-events/article.md

+39-40
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ Here's a list of the most useful DOM events, just to take a look at:
1111
- `mousedown` / `mouseup` -- when the mouse button is pressed / released over an element.
1212
- `mousemove` -- when the mouse is moved.
1313

14+
**Keyboard events:**
15+
- `keydown` and `keyup` -- when a keyboard key is pressed and released.
16+
1417
**Form element events:**
1518
- `submit` -- when the visitor submits a `<form>`.
1619
- `focus` -- when the visitor focuses on an element, e.g. on an `<input>`.
1720

18-
**Keyboard events:**
19-
- `keydown` and `keyup` -- when the visitor presses and then releases the button.
20-
2121
**Document events:**
2222
- `DOMContentLoaded` -- when the HTML is loaded and processed, DOM is fully built.
2323

@@ -87,8 +87,6 @@ If the handler is assigned using an HTML-attribute then the browser reads it, cr
8787

8888
So this way is actually the same as the previous one.
8989

90-
**The handler is always in the DOM property: the HTML-attribute is just one of the ways to initialize it.**
91-
9290
These two code pieces work the same:
9391

9492
1. Only HTML:
@@ -109,6 +107,8 @@ These two code pieces work the same:
109107
</script>
110108
```
111109

110+
In the first example, the HTML attribute is used to initialize the `button.onclick`, while in the second example -- the script, that's all the difference.
111+
112112
**As there's only one `onclick` property, we can't assign more than one event handler.**
113113

114114
In the example below adding a handler with JavaScript overwrites the existing handler:
@@ -124,16 +124,6 @@ In the example below adding a handler with JavaScript overwrites the existing ha
124124
</script>
125125
```
126126

127-
By the way, we can assign an existing function as a handler directly:
128-
129-
```js
130-
function sayThanks() {
131-
alert('Thanks!');
132-
}
133-
134-
elem.onclick = sayThanks;
135-
```
136-
137127
To remove a handler -- assign `elem.onclick = null`.
138128

139129
## Accessing the element: this
@@ -150,7 +140,17 @@ In the code below `button` shows its contents using `this.innerHTML`:
150140

151141
If you're starting to work with events -- please note some subtleties.
152142

153-
**The function should be assigned as `sayThanks`, not `sayThanks()`.**
143+
We can set an existing function as a handler:
144+
145+
```js
146+
function sayThanks() {
147+
alert('Thanks!');
148+
}
149+
150+
elem.onclick = sayThanks;
151+
```
152+
153+
But be careful: the function should be assigned as `sayThanks`, not `sayThanks()`.
154154

155155
```js
156156
// right
@@ -160,29 +160,25 @@ button.onclick = sayThanks;
160160
button.onclick = sayThanks();
161161
```
162162

163-
If we add parentheses, `sayThanks()` -- is a function call. So the last line actually takes the *result* of the function execution, that is `undefined` (as the function returns nothing), and assigns it to `onclick`. That doesn't work.
163+
If we add parentheses, then `sayThanks()` becomes is a function call. So the last line actually takes the *result* of the function execution, that is `undefined` (as the function returns nothing), and assigns it to `onclick`. That doesn't work.
164164

165165
...On the other hand, in the markup we do need the parentheses:
166166

167167
```html
168168
<input type="button" id="button" onclick="sayThanks()">
169169
```
170170

171-
The difference is easy to explain. When the browser reads the attribute, it creates a handler function with *body from its content*: `sayThanks()`.
171+
The difference is easy to explain. When the browser reads the attribute, it creates a handler function with body from the attribute content.
172172

173173
So the markup generates this property:
174174
```js
175175
button.onclick = function() {
176176
*!*
177-
sayThanks(); // the attribute content
177+
sayThanks(); // <-- the attribute content goes here
178178
*/!*
179179
};
180180
```
181181

182-
**Use functions, not strings.**
183-
184-
The assignment `elem.onclick = "alert(1)"` would work too. It works for compatibility reasons, but is strongly not recommended.
185-
186182
**Don't use `setAttribute` for handlers.**
187183

188184
Such a call won't work:
@@ -201,7 +197,7 @@ Assign a handler to `elem.onclick`, not `elem.ONCLICK`, because DOM properties a
201197

202198
The fundamental problem of the aforementioned ways to assign handlers -- we can't assign multiple handlers to one event.
203199

204-
For instance, one part of our code wants to highlight a button on click, and another one wants to show a message.
200+
Let's say, one part of our code wants to highlight a button on click, and another one wants to show a message on the same click.
205201

206202
We'd like to assign two event handlers for that. But a new DOM property will overwrite the existing one:
207203

@@ -211,7 +207,7 @@ input.onclick = function() { alert(1); }
211207
input.onclick = function() { alert(2); } // replaces the previous handler
212208
```
213209

214-
Web-standard developers understood that long ago and suggested an alternative way of managing handlers using special methods `addEventListener` and `removeEventListener`. They are free of such a problem.
210+
Developers of web standards understood that long ago and suggested an alternative way of managing handlers using special methods `addEventListener` and `removeEventListener`. They are free of such a problem.
215211

216212
The syntax to add a handler:
217213

@@ -229,8 +225,7 @@ element.addEventListener(event, handler, [options]);
229225
: An additional optional object with properties:
230226
- `once`: if `true`, then the listener is automatically removed after it triggers.
231227
- `capture`: the phase where to handle the event, to be covered later in the chapter <info:bubbling-and-capturing>. For historical reasons, `options` can also be `false/true`, that's the same as `{capture: false/true}`.
232-
- `passive`: if `true`, then the handler will not `preventDefault()`, we'll cover that later in <info:default-browser-action>.
233-
228+
- `passive`: if `true`, then the handler will not call `preventDefault()`, we'll explain that later in <info:default-browser-action>.
234229

235230
To remove the handler, use `removeEventListener`:
236231

@@ -249,7 +244,7 @@ elem.addEventListener( "click" , () => alert('Thanks!'));
249244
elem.removeEventListener( "click", () => alert('Thanks!'));
250245
```
251246
252-
The handler won't be removed, because `removeEventListener` gets another function -- with the same code, but that doesn't matter.
247+
The handler won't be removed, because `removeEventListener` gets another function -- with the same code, but that doesn't matter, as it's a different function object.
253248
254249
Here's the right way:
255250
@@ -291,31 +286,33 @@ Multiple calls to `addEventListener` allow to add multiple handlers, like this:
291286
As we can see in the example above, we can set handlers *both* using a DOM-property and `addEventListener`. But generally we use only one of these ways.
292287

293288
````warn header="For some events, handlers only work with `addEventListener`"
294-
There exist events that can't be assigned via a DOM-property. Must use `addEventListener`.
289+
There exist events that can't be assigned via a DOM-property. Only with `addEventListener`.
295290

296-
For instance, the event `DOMContentLoaded`, that triggers when the document is loaded and DOM is built.
291+
For instance, the `DOMContentLoaded` event, that triggers when the document is loaded and DOM is built.
297292

298293
```js
294+
// will never run
299295
document.onDOMContentLoaded = function() {
300-
alert("DOM built"); // will never run
296+
alert("DOM built");
301297
};
302298
```
303299

304300
```js
301+
// this way it works
305302
document.addEventListener("DOMContentLoaded", function() {
306-
alert("DOM built"); // this way it works
303+
alert("DOM built");
307304
});
308305
```
309306
So `addEventListener` is more universal. Although, such events are an exception rather than the rule.
310307
````
311308
312309
## Event object
313310
314-
To properly handle an event we'd want to know more about what's happened. Not just a "click" or a "keypress", but what were the pointer coordinates? Which key was pressed? And so on.
311+
To properly handle an event we'd want to know more about what's happened. Not just a "click" or a "keydown", but what were the pointer coordinates? Which key was pressed? And so on.
315312
316313
When an event happens, the browser creates an *event object*, puts details into it and passes it as an argument to the handler.
317314
318-
Here's an example of getting mouse coordinates from the event object:
315+
Here's an example of getting pointer coordinates from the event object:
319316
320317
```html run
321318
<input type="button" value="Click me" id="elem">
@@ -338,11 +335,11 @@ Some properties of `event` object:
338335
: Element that handled the event. That's exactly the same as `this`, unless the handler is an arrow function, or its `this` is bound to something else, then we can get the element from `event.currentTarget`.
339336
340337
`event.clientX / event.clientY`
341-
: Window-relative coordinates of the cursor, for mouse events.
338+
: Window-relative coordinates of the cursor, for pointer events.
342339
343-
There are more properties. They depend on the event type, so we'll study them later when we come to different events in details.
340+
There are more properties. Many of them depend on the event type: keyboard events have one set of properties, pointer events - another one, we'll study them later when we come to different events in details.
344341
345-
````smart header="The event object is also accessible from HTML"
342+
````smart header="The event object is also available in HTML handlers"
346343
If we assign a handler in HTML, we can also use the `event` object, like this:
347344
348345
```html autorun height=60
@@ -364,15 +361,17 @@ For instance:
364361
<button id="elem">Click me</button>
365362

366363
<script>
367-
elem.addEventListener('click', {
364+
let obj = {
368365
handleEvent(event) {
369366
alert(event.type + " at " + event.currentTarget);
370367
}
371-
});
368+
};
369+
370+
elem.addEventListener('click', obj);
372371
</script>
373372
```
374373

375-
As we can see, when `addEventListener` receives an object as the handler, it calls `object.handleEvent(event)` in case of an event.
374+
As we can see, when `addEventListener` receives an object as the handler, it calls `obj.handleEvent(event)` in case of an event.
376375

377376
We could also use a class for that:
378377

0 commit comments

Comments
 (0)