You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 2-ui/1-document/06-dom-attributes-and-properties/article.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -139,7 +139,7 @@ Please note:
139
139
140
140
1.`getAttribute('About')` -- the first letter is uppercase here, and in HTML it's all lowercase. But that doesn't matter: attribute names are case-insensitive.
141
141
2. We can assign anything to an attribute, but that becomes a string. So here we have `"123"` as the value.
142
-
3. All attributes including ones that we set are seen in `innerHTML`.
142
+
3. All attributes including ones that we set are visible in `outerHTML`.
143
143
4. The `attributes` collection is iterable and has all attributes with `name` and `value`.
Copy file name to clipboardExpand all lines: 2-ui/3-event-details/10-onload-ondomcontentloaded/article.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -67,7 +67,7 @@ There are two differences between them.
67
67
||`async`|`defer`|
68
68
|---------|---------|---------|
69
69
| Order | Scripts with `async` execute *in the load-first order*. Their document order doesn't matter -- which loads first runs first. | Scripts with `defer` always execute *in the document order* (as they go in the document). |
70
-
|`DOMContentLoaded`| Scripts with `async` may load and execute while the document has not yet been fully downloaded. | Scripts with `defer` execute after the document is loaded and parsed (they wait if needed), right before `DOMContentLoaded`. |
70
+
|`DOMContentLoaded`| Scripts with `async` may load and execute while the document has not yet been fully downloaded. That happens if scripts are small or cached, and the document is long enough. | Scripts with `defer` execute after the document is loaded and parsed (they wait if needed), right before `DOMContentLoaded`. |
71
71
72
72
So `async` is used for totally independent scripts.
Copy file name to clipboardExpand all lines: 5-animation/3-js-animation/article.md
+6-6Lines changed: 6 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -186,7 +186,7 @@ Function `animate` accepts 3 parameters that essentially describes the animation
186
186
187
187
Let's animate the element `width` from `0` to `100%` using our function.
188
188
189
-
Click for the demo:
189
+
Click on the element for the demo:
190
190
191
191
[codetabs height=60 src="width"]
192
192
@@ -410,19 +410,19 @@ As we can see, the graph of the first half of the animation is the scaled down `
410
410
411
411
## More interesting "draw"
412
412
413
-
Instead of moving the element we can do something else. All we need is to write the write `draw`
414
-
415
-
### Typing in the text
413
+
Instead of moving the element we can do something else. All we need is to write the write the proper `draw`.
416
414
417
415
Here's the animated "bouncing" text typing:
418
416
419
417
[codetabs src="text"]
420
418
421
419
## Summary
422
420
423
-
JavaScript animation is implemented with the help of `requestAnimationFrame`.
421
+
JavaScript animation should be implemented via `requestAnimationFrame`. That built-in method allows to setup a callback function to run when the browser will be preparing a repaint. Usually that's very soon, but the exact time depends on the browser.
422
+
423
+
When a page is in the background, there are no repaints at all, so the callback won't run: the animation will be suspended and won't consume resources. That's great.
424
424
425
-
The helper `animate` function:
425
+
Here's the helper `animate` function to setup most animations:
Copy file name to clipboardExpand all lines: 8-async/01-callback-hell/article.md
+22-11Lines changed: 22 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -30,32 +30,35 @@ A *synchronous* action suspends the execution until it's completed. For instance
30
30
```js
31
31
let age =prompt("How old are you", 20);
32
32
// the execution of the code below awaits for the prompt to finish
33
+
// the script hangs
33
34
```
34
35
35
36
An *asynchronous* action allows the program to continue while it's in progress. For instance, a call to `loadScript` is asynchronous. It initiates the script loading, but does not suspend the execution. Other commands may execute while the script is loading:
36
37
37
38
```js
38
39
loadScript('/my/script.js');
39
-
// the execution does not wait for the script loading to finish,
40
-
// it just goes on
40
+
// the execution of the code below *does not* wait for the script loading to finish,
41
+
// it just continues
41
42
```
42
43
43
-
As of now, `loadScript`provides no way to track the load completion. The script loads and eventually runs.
44
+
As of now, the `loadScript`function loads the script, doesn't provide a way to track the load completion. The script loads and eventually runs, that's all. But we'd like to know when happens, to use additional functions and variables from that script.
44
45
45
-
Let's add a `callback` function as a second argument to `loadScript`, that should execute at when the script is loaded.
46
+
Let's add a `callback` function as a second argument to `loadScript` that should execute when the script loads:
46
47
47
48
```js
48
49
functionloadScript(src, callback) {
49
50
let script =document.createElement('script');
50
51
script.src= src;
51
52
53
+
*!*
52
54
script.onload= () =>callback(script);
55
+
*/!*
53
56
54
57
document.head.append(script);
55
58
}
56
59
```
57
60
58
-
Now we're able to load a script and run our code that can use new functions from it, like here:
61
+
Now we're able to load a script and then run our code that can use new functions from it, like here:
59
62
60
63
```js run
61
64
functionloadScript(src, callback) {
@@ -73,7 +76,9 @@ loadScript('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js', f
73
76
*/!*
74
77
```
75
78
76
-
That's called a "callback style" of asynchronous programming. A function that does something asynchronously provides a callback argument where we put the code to run after it's complete.
79
+
That's called a "callback-based" style of asynchronous programming. A function that does something asynchronously should provide a `callback` argument where we put the function to run after it's complete.
80
+
81
+
Here it was used for `loadScript`, but of course it's a general approach.
1. The first argument of `callback` is reserved for an error if it occurs.
155
-
2. The second argument (and successive ones if needed) are for the successful result.
159
+
1. The first argument of `callback` is reserved for an error if it occurs. Then `callback(err)` is called.
160
+
2. The second argument and successive ones if needed are for the successful result. Then `callback(null, result1, result2…)` is called.
156
161
157
-
So the single `callback` function is used both for reporting errors and passing back results.
162
+
So the single `callback` function is used both for reporting errors and passing back results. That's called "error-first callback" style. Or we could use different functions for successful and erroneous completion.
158
163
159
164
## Pyramid of doom
160
165
@@ -203,6 +208,8 @@ That's sometimes called "callback hell" or "pyramid of doom".
203
208
204
209
The pyramid grows to the right with every asynchronous action. Soon it spirales out of control.
205
210
211
+
So this way of coding appears not so good.
212
+
206
213
In simple cases we can evade the problem by making every action a standalone function, like this:
207
214
208
215
```js
@@ -235,6 +242,10 @@ function step3(error, script) {
235
242
};
236
243
```
237
244
238
-
See? There's no deep nesting now, because we moved every function to the top. But the code looks like a torn apart spreadsheet. We need to eye-jump between pieces while reading it. The functions `step*` have no use, they are only created to evade the "pyramid of doom".
245
+
See? It does the same, and there's no deep nesting now, because we moved every function to the top. But the code looks like a torn apart spreadsheet. We need to eye-jump between pieces while reading it. It's not very readable, especially if you are not familiar with it and don't know where to eye-jump.
246
+
247
+
Also the functions `step*` have no use, they are only created to evade the "pyramid of doom".
248
+
249
+
So we'd like to have a better way of coding for complex asynchronous actions.
239
250
240
-
Luckily, there are other ways to evade such pyramids. Most modern code makes use of "promises", we'll study them in the next chapter.
251
+
Luckily, there are other ways to evade such pyramids. For instance, we can use "promises", described in the next chapter.
0 commit comments