diff --git a/1-js/01-getting-started/1-intro/article.md b/1-js/01-getting-started/1-intro/article.md
index 74521076..69bb189a 100644
--- a/1-js/01-getting-started/1-intro/article.md
+++ b/1-js/01-getting-started/1-intro/article.md
@@ -25,12 +25,12 @@ The browser has an embedded engine, sometimes it's also called a "JavaScript vir
Different engines have different "codenames", for example:
- [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- in Chrome and Opera.
-- [Gecko](https://en.wikipedia.org/wiki/Gecko_(software)) -- in Firefox.
+- [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- in Firefox.
- ...There are other codenames like "Trident", "Chakra" for different versions of IE, "ChakraCore" for Microsoft Edge, "Nitro" and "SquirrelFish" for Safari etc.
The terms above are good to remember, because they are used in developer articles on the internet. We'll use them too. For instance, if "a feature X is supported by V8", then it probably works in Chrome and Opera.
-```smart header="How engines work?"
+```smart header="How do engines work?"
Engines are complicated. But the basics are easy.
@@ -108,7 +108,7 @@ Modern tools make the transpilation very fast and transparent, actually allowing
Examples of such languages:
-- [CoffeeScript](http://coffeescript.org/) is a "syntax sugar" for JavaScript, it introduces shorter syntax, allowing to write more precise and clear code. Usually Ruby devs like it.
+- [CoffeeScript](http://coffeescript.org/) is a "syntactic sugar" for JavaScript, it introduces shorter syntax, allowing to write more precise and clear code. Usually Ruby devs like it.
- [TypeScript](http://www.typescriptlang.org/) is concentrated on adding "strict data typing", to simplify development and support of complex systems. It is developed by Microsoft.
- [Dart](https://www.dartlang.org/) is a standalone language that has its own engine that runs in non-browser environments (like mobile apps). It was initially offered by Google as a replacement for JavaScript, but as of now, browsers require it to be transpiled to JavaScript just like the ones above.
diff --git a/1-js/01-getting-started/2-code-editors/article.md b/1-js/01-getting-started/2-code-editors/article.md
index 65ef7476..0d714cdb 100644
--- a/1-js/01-getting-started/2-code-editors/article.md
+++ b/1-js/01-getting-started/2-code-editors/article.md
@@ -1,26 +1,22 @@
# Code editors
-A code editor is the place where a programmer spends most of his time.
+A code editor is the place where programmers spend most of their time.
There are two archetypes: IDE and lightweight editors. Many people feel comfortable choosing one tool of each type.
-[cut]
-
## IDE
-The term [IDE](https://en.wikipedia.org/wiki/Integrated_development_environment) (Integrated Development Environment) means a powerful editor with many features that usually operates on a "whole project". As said, that's not just an editor, but a full-scale "development environment".
+The term [IDE](https://en.wikipedia.org/wiki/Integrated_development_environment) (Integrated Development Environment) means a powerful editor with many features that usually operates on a "whole project". As the name suggests, that's not just an editor, but a full-scale "development environment".
-An IDE loads the project (can be many files), and then allows navigation between files, provides autocompletion based on the whole project, integrates with a version management system (like [git](https://git-scm.com/)), a testing environment and other "project-level" stuff.
+An IDE loads the project (can be many files), allows navigation between files, provides autocompletion based on the whole project (not just the open file), integrates with a version management system (like [git](https://git-scm.com/)), a testing environment and other "project-level" stuff.
If you haven't considered selecting an IDE yet, look at the following variants:
-- IntelliJ editors: [WebStorm](http://www.jetbrains.com/webstorm/) for frontend development and [PHPStorm (PHP)](http://www.jetbrains.com/phpstorm/), [IDEA (Java)](http://www.jetbrains.com/idea/), [RubyMine (Ruby)](http://www.jetbrains.com/ruby/) and others if you need additional languages.
+- [WebStorm](http://www.jetbrains.com/webstorm/) for frontend development and other editors of the same company if you need additional languages.
- Visual Studio is fine if you're a .NET developer, and a free version is available ([Visual Studio Community](https://www.visualstudio.com/vs/community/))
-- Eclipse-based products, like [Aptana](http://www.aptana.com/) and Zend Studio.
-- [Komodo IDE](http://www.activestate.com/komodo-ide) and its lightweight free version [Komodo Edit](http://www.activestate.com/komodo-edit).
- [Netbeans](http://netbeans.org/).
-All of the IDEs listed above are available on both Windows and Mac, and the IDEs other than Visual Studio are also available on Linux.
+All of the IDEs except Visual Studio are available on Windows, MacOs and Linux. Visual Studio doesn't work on Linux.
Most IDEs are paid, but have a trial period. Their cost is usually negligible compared to a qualified developer's salary, so just choose the best one for you.
@@ -40,7 +36,7 @@ The following options deserve your attention:
- [Atom](https://atom.io/) (cross-platform, free).
- [Sublime Text](http://www.sublimetext.com) (cross-platform, shareware).
- [Notepad++](https://notepad-plus-plus.org/) (Windows, free).
-- Vim and Emacs are also cool, if you know how to use them.
+- [Vim](http://www.vim.org/) and [Emacs](https://www.gnu.org/software/emacs/) are also cool, if you know how to use them.
## My favorites
@@ -48,11 +44,9 @@ The personal preference of the author is to have both an IDE for projects and a
I'm using:
-- [WebStorm](http://www.jetbrains.com/webstorm/) for JS, and if there is one more language in the project, then I switch to other Jetbrains editors like [PHPStorm](http://www.jetbrains.com/phpstorm/) (PHP), [IDEA](http://www.jetbrains.com/idea/) (Java), [RubyMine](http://www.jetbrains.com/ruby/) (Ruby). There are editors for other languages too, but I haven't used them.
+- [WebStorm](http://www.jetbrains.com/webstorm/) for JS, and if there is one more language in the project, then I switch to one of the other Jetbrains offerings listed above.
- As a lightweight editor -- [Sublime Text](http://www.sublimetext.com) or [Atom](https://atom.io/).
-If you don't know what to choose, you can consider these ones.
-
## Let's not argue
The editors in the lists above are those that either I or my friends who I consider good developers have been using for a long time and are happy with.
diff --git a/1-js/01-getting-started/3-devtools/article.md b/1-js/01-getting-started/3-devtools/article.md
index 34e5c9a7..f250502d 100644
--- a/1-js/01-getting-started/3-devtools/article.md
+++ b/1-js/01-getting-started/3-devtools/article.md
@@ -10,8 +10,6 @@ Most often developers lean towards Chrome or Firefox for development, because th
Developer tools are really powerful, there are many features. To start, we'll learn how to open them, look at errors and run JavaScript commands.
-[cut]
-
## Google Chrome
Open the page [bug.html](bug.html).
diff --git a/1-js/02-first-steps/01-hello-world/article.md b/1-js/02-first-steps/01-hello-world/article.md
index e69a25f0..69d2ba97 100644
--- a/1-js/02-first-steps/01-hello-world/article.md
+++ b/1-js/02-first-steps/01-hello-world/article.md
@@ -7,8 +7,6 @@ But, we need a working environment to run our scripts, and, just because this bo
So first, let's see how to attach a script to a webpage. For server-side environments, you can just execute it with a command like `"node my.js"` for Node.JS.
-[cut]
-
## The "script" tag
JavaScript programs can be inserted in any part of an HTML document with the help of the `
```online
-On the picture above element nodes you can click on element nodes. Their children will open/collapse.
+On the picture above, you can click on element nodes and their children will open/collapse.
```
-Tags are called *element nodes* (or just elements). Nested tags become children of the enclosing ones. As a result we have a tree of elements: `` is at the root, then `
` and `` are its children etc.
+Tags are called *element nodes* (or just elements). Nested tags become children of the enclosing ones. As a result we have a tree of elements: `` is at the root, then `` and `` are its children, etc.
The text inside elements forms *text nodes*, labelled as `#text`. A text node contains only a string. It may not have children and is always a leaf of the tree.
@@ -55,13 +55,13 @@ Please note the special characters in text nodes:
- a newline: `↵` (in JavaScript known as `\n`)
- a space: `␣`
-Spaces and newlines -- are totally valid characters, they form text nodes and become a part of the DOM. So, for instance, in the example above the `` tag contains come spaces before ``, and that text becomes a `#text` node (it contains a newline and some spaces only).
+Spaces and newlines -- are totally valid characters, they form text nodes and become a part of the DOM. So, for instance, in the example above the `` tag contains some spaces before ``, and that text becomes a `#text` node (it contains a newline and some spaces only).
There are only two top-level exclusions:
1. Spaces and newlines before `` are ignored for historical reasons,
-2. If we put something after ``, then that is automatically moved inside the `body`, at the end, as HTML spec requires that all content must be inside ``. So there may be no spaces after ``.
+2. If we put something after ``, then that is automatically moved inside the `body`, at the end, as the HTML spec requires that all content must be inside ``. So there may be no spaces after ``.
-In other cases everything's honest -- if there are spaces (just like any character) in the document, then they text nodes in DOM, and if we remove them, then there won't be any.
+In other cases everything's straightforward -- if there are spaces (just like any character) in the document, then they become text nodes in DOM, and if we remove them, then there won't be any.
Here are no space-only text nodes:
@@ -79,9 +79,9 @@ drawHtmlTree(node2, 'div.domtree', 690, 210);
```smart header="Edge spaces and in-between empty text are usually hidden in tools"
-Browser tools (to be covered soon) that work with DOM usually do not show spaces at start/end of the text and empty text nodes (line-breaks) between tags. .
+Browser tools (to be covered soon) that work with DOM usually do not show spaces at the start/end of the text and empty text nodes (line-breaks) between tags.
-That's because they are mainly used to decorate HTML, and do not affect (in most cases) how it is shown.
+That's because they are mainly used to decorate HTML, and do not affect how it is shown (in most cases).
On further DOM pictures we'll sometimes omit them where they are irrelevant, to keep things short.
```
@@ -91,7 +91,7 @@ On further DOM pictures we'll sometimes omit them where they are irrelevant, to
If the browser encounters malformed HTML, it automatically corrects it when making DOM.
-For instance, the top tag is always ``. Even if it doesn't exist in the document -- it will be in DOM, the browser will create it. The same about ``.
+For instance, the top tag is always ``. Even if it doesn't exist in the document -- it will exist in the DOM, the browser will create it. The same goes for ``.
As an example, if the HTML file is a single word `"Hello"`, the browser will wrap it into `` and ``, add the required ``, and the DOM will be:
@@ -104,7 +104,7 @@ let node3 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,
drawHtmlTree(node3, 'div.domtree', 690, 150);
-While generating DOM, browser automatically processes errors in the document, closes tags and so on.
+While generating the DOM, browsers automatically process errors in the document, close tags and so on.
Such an "invalid" document:
@@ -115,7 +115,7 @@ Such an "invalid" document:
Dad
```
-...Will become a normal DOM, as the browser read tags and restores the missing parts:
+...Will become a normal DOM, as the browser reads tags and restores the missing parts:
@@ -143,7 +143,7 @@ let node5 = {"name":"TABLE","nodeType":1,"children":[{"name":"TBODY","nodeType":
drawHtmlTree(node5, 'div.domtree', 600, 200);
-You see? The `` has appeared out of nowhere. Should keep in mind while working with tables to evade surprises.
+You see? The `` appeared out of nowhere. You should keep this in mind while working with tables to avoid surprises.
````
## Other node types
@@ -178,7 +178,7 @@ Here we see a new tree node type -- *comment node*, labeled as `#comment`.
We may think -- why a comment is added to the DOM? It doesn't affect the visual representation in any way. But there's a rule -- if something's in HTML, then it also must be in the DOM tree.
-**Everything in HTML, even comments, becomes a part of DOM.**
+**Everything in HTML, even comments, becomes a part of the DOM.**
Even the `` directive at the very beginning of HTML is also a DOM node. It's in the DOM tree right before ``. We are not going to touch that node, we even don't draw it on diagrams for that reason, but it's there.
@@ -189,39 +189,39 @@ There are [12 node types](https://dom.spec.whatwg.org/#node). In practice we usu
1. `document` -- the "entry point" into DOM.
2. element nodes -- HTML-tags, the tree building blocks.
3. text nodes -- contain text.
-4. comments -- sometimes we can put the information there, it won't be shown, but JS can read it from DOM.
+4. comments -- sometimes we can put the information there, it won't be shown, but JS can read it from the DOM.
-## See it yourself
+## See it for yourself
-To see the DOM structure in real-time, try [Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/). Just type in the document, and it will show up DOM at instant.
+To see the DOM structure in real-time, try [Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/). Just type in the document, and it will show up DOM at an instant.
## In the browser inspector
-Another way to explore DOM is to use browser developer tools. Actually, that's what we use when developing.
+Another way to explore the DOM is to use the browser developer tools. Actually, that's what we use when developing.
-To do so, open the web-page [elks.html](elks.html), turn on browser developer tools and switch to Elements tab.
+To do so, open the web-page [elks.html](elks.html), turn on the browser developer tools and switch to the Elements tab.
-Should look like this:
+It should look like this:

You can see the DOM, click on elements, see their details and so on.
-Please note that the DOM structure in developer tools is simplified. Text nodes are shown just as text. And there are no "blank" (space only) text nodes at all. That's fine, because most of time we are interested in element nodes.
+Please note that the DOM structure in developer tools is simplified. Text nodes are shown just as text. And there are no "blank" (space only) text nodes at all. That's fine, because most of the time we are interested in element nodes.
-Clicking the button in the left-upper corner allows to choose a node from the webpage using a mouse (or other pointer device) and "inspect" it (scroll to it in the elements tab). Works great when we have a huge HTML page and would like to see the DOM of a particular place in it.
+Clicking the button in the left-upper corner allows to choose a node from the webpage using a mouse (or other pointer devices) and "inspect" it (scroll to it in the Elements tab). This works great when we have a huge HTML page (and corresponding huge DOM) and would like to see the place of a particual element in it.
Another way to do it would be just right-clicking on a webpage and selecting "Inspect" in the context menu.

-At the right part of the tools there are following subtabs:
-- Styles -- we can see CSS applied to the current element rule by rule, including built-in rules (gray). Almost everything can be edited at-place including the dimensions/margins/paddings of the box below.
-- Computed -- to see CSS applied to the element by property: for each property we can see a rule that gives it (including CSS inheritance and such).
-- Event Listeners -- to see event listeners attached to DOM elements (we'll cover them in the next part of the tutorial).
+At the right part of the tools there are the following subtabs:
+- **Styles** -- we can see CSS applied to the current element rule by rule, including built-in rules (gray). Almost everything can be edited in-place, including the dimensions/margins/paddings of the box below.
+- **Computed** -- to see CSS applied to the element by property: for each property we can see a rule that gives it (including CSS inheritance and such).
+- **Event Listeners** -- to see event listeners attached to DOM elements (we'll cover them in the next part of the tutorial).
- ...and so on.
-The best way to study them is to click around. Most values are in-place editable.
+The best way to study them is to click around. Most values are editable in-place.
## Interaction with console
@@ -244,7 +244,7 @@ Or we can just output it in the console and explore "at-place", like `document.b
That's for debugging purposes of course. From the next chapter on we'll access and modify DOM using JavaScript.
-The browser developer tools are a great help in development: we can explore DOM, try things and see what goes wrong.
+The browser developer tools are a great help in development: we can explore the DOM, try things and see what goes wrong.
## Summary
@@ -256,6 +256,6 @@ An HTML/XML document is represented inside the browser as the DOM tree.
We can use developer tools to inspect DOM and modify it manually.
-Here we covered the basics, most used and important actions to start with. There's an extensive documentation about Chrome developer tools at . The best way to learn the tools is to click here and there, read menus: most options are obvious. Later, when you know them in general, read the docs and pick up the rest.
+Here we covered the basics, the most used and important actions to start with. There's an extensive documentation about Chrome Developer Tools at . The best way to learn the tools is to click here and there, read menus: most options are obvious. Later, when you know them in general, read the docs and pick up the rest.
DOM nodes have properties and methods that allow to travel between them, modify, move around the page and more. We'll get down to them in the next chapters.
diff --git a/2-ui/1-document/03-dom-navigation/article.md b/2-ui/1-document/03-dom-navigation/article.md
index ab96e5f7..976e595a 100644
--- a/2-ui/1-document/03-dom-navigation/article.md
+++ b/2-ui/1-document/03-dom-navigation/article.md
@@ -7,11 +7,9 @@ libs:
# Walking the DOM
-DOM allows to do anything with elements and their contents, but first we need to reach the corresponding DOM object, get it into a variable, and then we are able to modify it.
+The DOM allows to do anything with elements and their contents, but first we need to reach the corresponding DOM object, get it into a variable, and then we are able to modify it.
-All operations on DOM start with the `document` object. From it we can access any node.
-
-[cut]
+All operations on the DOM start with the `document` object. From it we can access any node.
Here's a picture of links that allow to travel between DOM nodes:
@@ -88,7 +86,7 @@ For instance, here `` has children `
` and `
` (and few blank text
```
-...And if we ask for all descendants of ``, then we get direct children `
`, `
` and also more nested elements like `
` (being a child of `
`) and `` (being a child of `
`) -- the whole subtree.
+...And if we ask for all descendants of ``, then we get direct children `
`, `
` and also more nested elements like `
` (being a child of `
`) and `` (being a child of `
`) -- the entire subtree.
**The `childNodes` collection provides access to all child nodes, including text nodes.**
@@ -157,7 +155,7 @@ The first thing is nice. The second is tolerable, because we can use `Array.from
```warn header="DOM collections are read-only"
DOM collections, and even more -- *all* navigation properties listed in this chapter are read-only.
-We can't replace an child by something else assigning `childNodes[i] = ...`.
+We can't replace a child by something else assigning `childNodes[i] = ...`.
Changing DOM needs other methods, we'll see them in the next chapter.
```
@@ -177,7 +175,7 @@ Please, don't. The `for..in` loop iterates over all enumerable properties. And c
````
@@ -242,7 +240,7 @@ In other words, the `documentElement` (``) is the root node. Formally, it
Sometimes that matters when we're walking over the chain of parents and call a method on each of them, but `document` doesn't have it, so we exclude it.
````
-Let's modify one of examples above: replace `childNodes` with `children`. Now it shows only elements:
+Let's modify one of the examples above: replace `childNodes` with `children`. Now it shows only elements:
```html run
@@ -275,7 +273,7 @@ Certain types of DOM elements may provide additional properties, specific to the
Tables are a great example and important particular case of that.
-**`
`** element supports (in addition to the given above) these properties:
+**The `
`** element supports (in addition to the given above) these properties:
- `table.rows` -- the collection of `
` elements of the table.
- `table.caption/tHead/tFoot` -- references to elements `
`, `
`, `
`.
- `table.tBodies` -- the collection of `` elements (can be many according to the standard).
@@ -285,8 +283,8 @@ Tables are a great example and important particular case of that.
**`
`:**
- `tr.cells` -- the collection of `
` and `
` cells inside the given `
`.
-- `tr.sectionRowIndex` -- the number of the given `
` inside the enclosing `/
`.
-- `tr.rowIndex` -- the number of the `
` in the table.
+- `tr.sectionRowIndex` -- the position (index) of the given `
` inside the enclosing `/
/`.
+- `tr.rowIndex` -- the number of the `
` in the table as a whole (including all table rows).
**`
` and `
`:**
- `td.cellIndex` -- the number of the cell inside the enclosing `
`.
diff --git a/2-ui/1-document/04-searching-elements-dom/1-find-elements/solution.md b/2-ui/1-document/04-searching-elements-dom/1-find-elements/solution.md
index 0ada42ac..c7080388 100644
--- a/2-ui/1-document/04-searching-elements-dom/1-find-elements/solution.md
+++ b/2-ui/1-document/04-searching-elements-dom/1-find-elements/solution.md
@@ -25,7 +25,7 @@ let form = document.getElementsByName('search')[0]
document.querySelector('form[name="search"]')
// 5. The first input in that form.
-form.getElementsByTagName('input')
+form.getElementsByTagName('input')[0]
// or
form.querySelector('input')
diff --git a/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.md b/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.md
index 5bb2effa..781b7a92 100644
--- a/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.md
+++ b/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.md
@@ -1,7 +1,7 @@
Let's make a loop over `
`:
```js
-for (let li of document.querySelector('li')) {
+for (let li of document.querySelectorAll('li')) {
...
}
```
@@ -9,7 +9,7 @@ for (let li of document.querySelector('li')) {
In the loop we need to get the text inside every `li`. We can read it directly from the first child node, that is the text node:
```js
-for (let li of document.querySelector('li')) {
+for (let li of document.querySelectorAll('li')) {
let title = li.firstChild.data;
// title is the text in
before any other nodes
diff --git a/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.view/index.html b/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.view/index.html
index d712bb9d..5947ec09 100644
--- a/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.view/index.html
+++ b/2-ui/1-document/04-searching-elements-dom/2-tree-info/solution.view/index.html
@@ -40,7 +40,7 @@
@@ -138,15 +136,15 @@ Here's an extended demo of working with attributes:
Please note:
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.
-2. We can assign anything to an attribute, but that becomes a string. So here we have `"123"` as the value.
+2. We can assign anything to an attribute, but it becomes a string. So here we have `"123"` as the value.
3. All attributes including ones that we set are visible in `outerHTML`.
4. The `attributes` collection is iterable and has all attributes with `name` and `value`.
## Property-attribute synchronization
-When a standard attribute changes, the corresponding property is auto-updated, and (with some exceptions) vise-versa.
+When a standard attribute changes, the corresponding property is auto-updated, and (with some exceptions) vice versa.
-In the example below `id` is modified as an attribute, and we can see the property change too. And then the same backwards:
+In the example below `id` is modified as an attribute, and we can see the property changed too. And then the same backwards:
```html run
@@ -188,11 +186,11 @@ In the example above:
- Changing the attribute `value` updates the property.
- But the property change does not affect the attribute.
-That "feature" may actually can come in handy, because the user may modify `value`, and then after it, if we want to recover the "original" value from HTML, it's in the attribute.
+That "feature" may actually come in handy, because the user may modify `value`, and then after it, if we want to recover the "original" value from HTML, it's in the attribute.
## DOM properties are typed
-DOM properties are not always strings. For instance, `input.checked` property (for checkboxes) is boolean:
+DOM properties are not always strings. For instance, the `input.checked` property (for checkboxes) is a boolean:
```html run
checkbox
@@ -203,7 +201,7 @@ DOM properties are not always strings. For instance, `input.checked` property (f
```
-There are other examples. The `style` attribute is a string, but `style` property is an object:
+There are other examples. The `style` attribute is a string, but the `style` property is an object:
```html run
Hello
@@ -311,9 +309,9 @@ div.setAttribute('order-state', 'canceled');
But there may be a possible problem with custom attributes. What if we use a non-standard attribute for our purposes and later the standard introduces it and makes it do something? The HTML language is alive, it grows, more attributes appear to suit the needs of developers. There may be unexpected effects in such case.
-To evade conflicts, there exist [data-*](https://html.spec.whatwg.org/#embedding-custom-non-visible-data-with-the-data-*-attributes) attributes.
+To avoid conflicts, there exist [data-*](https://html.spec.whatwg.org/#embedding-custom-non-visible-data-with-the-data-*-attributes) attributes.
-**All attributes starting with "data-" are reserved for programmers' use. They are available in `dataset` property.**
+**All attributes starting with "data-" are reserved for programmers' use. They are available in the `dataset` property.**
For instance, if an `elem` has an attribute named `"data-about"`, it's available as `elem.dataset.about`.
@@ -382,7 +380,7 @@ Methods to work with attributes are:
- `elem.removeAttribute(name)` -- to remove the attribute.
- `elem.attributes` is a collection of all attributes.
-For most needs DOM properties can serve us well. We should refer to attributes only when DOM properties do not suit us, when we need exactly attributes, for instance:
+For most needs, DOM properties can serve us well. We should refer to attributes only when DOM properties do not suit us, when we need exactly attributes, for instance:
- We need a non-standard attribute. But if it starts with `data-`, then we should use `dataset`.
-- We want to read the value "as written" in HTML. The value of the DOM property may be different, for instance `href` property is always a full URL, and we may want to get the "original" value.
+- We want to read the value "as written" in HTML. The value of the DOM property may be different, for instance the `href` property is always a full URL, and we may want to get the "original" value.
diff --git a/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md b/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md
index 25c1e819..6b85168b 100644
--- a/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md
+++ b/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md
@@ -4,6 +4,6 @@ The browser has to fix it automatically. But there may be no text inside the ``.
+The question can be easily answered by exploring the DOM using the browser tools. It shows `"aaa"` before the `
`.
The HTML standard specifies in detail how to process bad HTML, and such behavior of the browser is correct.
diff --git a/2-ui/1-document/07-modifying-document/5-why-aaa/task.md b/2-ui/1-document/07-modifying-document/5-why-aaa/task.md
index aedf8697..03064ed2 100644
--- a/2-ui/1-document/07-modifying-document/5-why-aaa/task.md
+++ b/2-ui/1-document/07-modifying-document/5-why-aaa/task.md
@@ -2,9 +2,9 @@ importance: 1
---
-# Why "aaa" remains?
+# Why does "aaa" remain?
-Run the example. Why `table.remove()` does not delete the text `"aaa"`?
+Run the example. Why does `table.remove()` not delete the text `"aaa"`?
```html height=100 run
diff --git a/2-ui/1-document/07-modifying-document/article.md b/2-ui/1-document/07-modifying-document/article.md
index adef6f9f..38e1199e 100644
--- a/2-ui/1-document/07-modifying-document/article.md
+++ b/2-ui/1-document/07-modifying-document/article.md
@@ -6,11 +6,9 @@ Here we'll see how to create new elements "on the fly" and modify the existing p
First we'll see a simple example and then explain the methods.
-[cut]
-
## Example: show a message
-For the start, let's see how to add a message on the page that looks nicer than `alert`.
+For a start, let's see how to add a message on the page that looks nicer than `alert`.
Here's how it will look:
@@ -32,7 +30,7 @@ Here's how it will look:
*/!*
```
-That was an HTML example. Now let's create the same `div` with JavaScript (assuming that the styles are still in the HTML or an external CSS).
+That was an HTML example. Now let's create the same `div` with JavaScript (assuming that the styles are still in the HTML or an external CSS file).
## Creating an element
@@ -63,7 +61,7 @@ div.className = "alert alert-success";
div.innerHTML = "Hi there! You've read an important message.";
```
-After that, we have a ready DOM element. Right now it's in the variable, but can not be seen, because not inserted into the page yet.
+After that, we have a ready DOM element. Right now it's in the variable, but can not be seen, because it's not been inserted into the page yet.
## Insertion methods
@@ -137,9 +135,8 @@ Here's a brief list of methods to insert a node into a parent element (`parentEl
*/!*
```
-
- To insert as the first element, we can do like this:
-
+ To insert `newLi` as the first element, we can do it like this:
+
```js
list.insertBefore(newLi, list.firstChild);
```
@@ -153,7 +150,7 @@ These methods are "old school": they exist from the ancient times and we can mee
For instance, how to insert *html* if we have it as a string? Or, given a node, how to insert another node *before* it? Of course, all that is doable, but not in an elegant way.
-So there exists two other sets of insertion methods to handle all cases easily.
+So there exist two other sets of insertion methods to handle all cases easily.
### prepend/append/before/after
@@ -206,7 +203,7 @@ before
after
```
-These methods can insert multiple list of nodes and text pieces in a single call.
+These methods can insert multiple lists of nodes and text pieces in a single call.
For instance, here a string and an element are inserted:
@@ -279,7 +276,7 @@ The method has two brothers:
- `elem.insertAdjacentText(where, text)` -- the same syntax, but a string of `text` in inserted "as text" instead of HTML,
- `elem.insertAdjacentElement(where, elem)` -- the same syntax, but inserts an element.
-They exist mainly to make the syntax "uniform". In practice, most of time only `insertAdjacentHTML` is used, because for elements and text we have methods `append/prepend/before/after` -- they are shorter to write and can insert nodes/text pieces.
+They exist mainly to make the syntax "uniform". In practice, most of the time only `insertAdjacentHTML` is used, because for elements and text we have methods `append/prepend/before/after` -- they are shorter to write and can insert nodes/text pieces.
So here's an alternative variant of showing a message:
@@ -305,7 +302,7 @@ So here's an alternative variant of showing a message:
How to insert one more similar message?
-We could do a function and put the code there. But the alternative way would be to *clone* the existing `div` and modify the text inside it (if needed).
+We could make a function and put the code there. But the alternative way would be to *clone* the existing `div` and modify the text inside it (if needed).
Sometimes when we have a big element, that may be faster and simpler.
@@ -340,7 +337,7 @@ An example of copying the message:
## Removal methods
-To remove nodes, there are following methods:
+To remove nodes, there are the following methods:
`parentElem.removeChild(node)`
@@ -414,7 +411,7 @@ The call to `document.write(html)` writes the `html` into page "right here and n
The method comes from times when there were no DOM, no standards... Really old times. It still lives, because there are scripts using it.
-In modern scripts we can rarely see it, because of the important limitation.
+In modern scripts we can rarely see it, because of the following important limitation:
**The call to `document.write` only works while the page is loading.**
@@ -482,4 +479,4 @@ Insertion and removal of nodes:
- To append HTML to the page before it has finished loading:
- `document.write(html)`
- After the page is loaded such call erases the document. Mostly seen in old scripts.
+ After the page is loaded such a call erases the document. Mostly seen in old scripts.
diff --git a/2-ui/1-document/08-styles-and-classes/2-create-notification/solution.view/index.html b/2-ui/1-document/08-styles-and-classes/2-create-notification/solution.view/index.html
index 5b8a6336..dc4eeec9 100755
--- a/2-ui/1-document/08-styles-and-classes/2-create-notification/solution.view/index.html
+++ b/2-ui/1-document/08-styles-and-classes/2-create-notification/solution.view/index.html
@@ -26,7 +26,7 @@
notification.style.top = top + 'px';
notification.style.right = right + 'px';
- notification.innerHTML = options.html;
+ notification.innerHTML = html;
document.body.append(notification);
setTimeout(() => notification.remove(), 1500);
diff --git a/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md b/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md
index 7df1986c..60930cb6 100644
--- a/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md
+++ b/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md
@@ -4,7 +4,7 @@ importance: 5
# Create a notification
-Write a function `showNotification(options)` that a notification: `
` with the given content. The notification should automatically disappear after 1.5 seconds.
+Write a function `showNotification(options)` that creates a notification: `
` with the given content. The notification should automatically disappear after 1.5 seconds.
The options are:
diff --git a/2-ui/1-document/08-styles-and-classes/article.md b/2-ui/1-document/08-styles-and-classes/article.md
index 1c5f0948..3227da15 100644
--- a/2-ui/1-document/08-styles-and-classes/article.md
+++ b/2-ui/1-document/08-styles-and-classes/article.md
@@ -7,8 +7,6 @@ There are generally two ways to style an element:
1. Create a class in CSS and add it: `
`
2. Write properties directly into `style`: `
`.
-[cut]
-
CSS is always the preferred way -- not only for HTML, but in JavaScript as well.
We should only manipulate the `style` property if classes "can't handle it".
@@ -26,7 +24,7 @@ For other cases, like making the text red, adding a background icon -- describe
## className and classList
-Changing a class is one of the most often actions in scripts.
+Changing a class is one of the most often used actions in scripts.
In the ancient time, there was a limitation in JavaScript: a reserved word like `"class"` could not be an object property. That limitation does not exist now, but at that time it was impossible to have a `"class"` property, like `elem.class`.
@@ -76,7 +74,7 @@ Besides that, `classList` is iterable, so we can list all classes like this:
```html run
@@ -209,7 +207,7 @@ For instance, here `style` doesn't see the margin:
```
-...But what if we need, say, increase the margin by 20px? We want the current value for the start.
+...But what if we need, say, to increase the margin by 20px? We want the current value for the start.
There's another method for that: `getComputedStyle`.
@@ -223,7 +221,7 @@ element
: Element to read the value for.
pseudo
-: A pseudo-element if required, for instance `::before`. An empty string or no argument mean the element itself.
+: A pseudo-element if required, for instance `::before`. An empty string or no argument means the element itself.
The result is an object with style properties, like `elem.style`, but now with respect to all CSS classes.
@@ -250,10 +248,10 @@ For instance:
```smart header="Computed and resolved values"
There are two concepts in [CSS](https://drafts.csswg.org/cssom/#resolved-values):
-1. A *computed* style value is the value after all CSS rules and CSS inheritance is applied, as the result of the CSS cascade. If can look like `height:1em` or `font-size:125%`.
+1. A *computed* style value is the value after all CSS rules and CSS inheritance is applied, as the result of the CSS cascade. It can look like `height:1em` or `font-size:125%`.
2. A *resolved* style value is the one finally applied to the element. Values like `1em` or `125%` are relative. The browser takes the computed value and makes all units fixed and absolute, for instance: `height:20px` or `font-size:16px`. For geometry properties resolved values may have a floating point, like `width:50.5px`.
-Long time ago `getComputedStyle` was created to get computed values, but it turned out that resolved values are much more convenient, and the standard changed.
+A long time ago `getComputedStyle` was created to get computed values, but it turned out that resolved values are much more convenient, and the standard changed.
So nowadays `getComputedStyle` actually returns the resolved value of the property.
```
@@ -283,7 +281,7 @@ Visited links may be colored using `:visited` CSS pseudoclass.
But `getComputedStyle` does not give access to that color, because otherwise an arbitrary page could find out whether the user visited a link by creating it on the page and checking the styles.
-JavaScript we may not see the styles applied by `:visited`. And also, there's a limitation in CSS that forbids to apply geometry-changing styles in `:visited`. That's to guarantee that there's no side way for an evil page to test if a link was visited and hence to break the privacy.
+JavaScript we may not see the styles applied by `:visited`. And also, there's a limitation in CSS that forbids to apply geometry-changing styles in `:visited`. That's to guarantee that there's no sideway for an evil page to test if a link was visited and hence to break the privacy.
```
## Summary
diff --git a/2-ui/1-document/09-size-and-scroll/article.md b/2-ui/1-document/09-size-and-scroll/article.md
index 375cb4d9..4fadba81 100644
--- a/2-ui/1-document/09-size-and-scroll/article.md
+++ b/2-ui/1-document/09-size-and-scroll/article.md
@@ -1,11 +1,9 @@
# Element size and scrolling
-There are many JavaScript properties that allow to read information about element width, height and other geometry features.
+There are many JavaScript properties that allow us to read information about element width, height and other geometry features.
We often need them when moving or positioning elements in JavaScript, to correctly calculate coordinates.
-[cut]
-
## Sample element
@@ -37,7 +35,7 @@ You can [open the document in the sandbox](sandbox:metric).
```smart header="Mind the scrollbar"
The picture above demonstrates the most complex case when the element has a scrollbar. Some browsers (not all) reserve the space for it by taking it from the content.
-So, without scrollbar the content width would be `300px`, but if the scrollbar is `16px` wide (the width may vary between devices and browsers) then only `300-16 = 284px` remains, and we should take it into account. That's why examples from this chapter assume that there's a scrollbar. If there's no scrollbar, then things are just a bit simpler.
+So, without scrollbar the content width would be `300px`, but if the scrollbar is `16px` wide (the width may vary between devices and browsers) then only `300 - 16 = 284px` remains, and we should take it into account. That's why examples from this chapter assume that there's a scrollbar. If there's no scrollbar, then things are just a bit simpler.
```
```smart header="The `padding-bottom` may be filled with text"
@@ -68,7 +66,7 @@ The `offsetParent` is the nearest ancestor that is:
In most practical cases we can use `offsetParent` to get the nearest CSS-positioned ancestor. And `offsetLeft/offsetTop` provide x/y coordinates relative to it's left-upper corner.
-In the example below the inner `
` has `` as `offsetParent` and `offsetLeft/offsetTop` are shifts from its left-upper corner (`180`):
+In the example below the inner `
` has `` as `offsetParent` and `offsetLeft/offsetTop` shifts from its left-upper corner (`180`):
```html run height=10
@@ -90,11 +88,11 @@ There are several occasions when `offsetParent` is `null`:
1. For not shown elements (`display:none` or not in the document).
2. For `` and ``.
-3. For elements with `position:fixed` on them.
+3. For elements with `position:fixed`.
## offsetWidth/Height
-Now let's move to the element itself.
+Now let's move on to the element itself.
These two properties are the simplest ones. They provide the "outer" width/height of the element. Or, in other words, its full size including borders.
@@ -102,7 +100,7 @@ These two properties are the simplest ones. They provide the "outer" width/heigh
For our sample element:
-- `offsetWidth = 390` -- the outer width, can be calculated as inner CSS-width (`300px`) plus paddings (`2*20px`) and borders (`2*25px`).
+- `offsetWidth = 390` -- the outer width, can be calculated as inner CSS-width (`300px`) plus paddings (`2 * 20px`) and borders (`2 * 25px`).
- `offsetHeight = 290` -- the outer height.
````smart header="Geometry properties for not shown elements are zero/null"
@@ -140,9 +138,9 @@ In our example:
What's the difference?
-It becomes visible when the document is right-to-left (the operation system is in arabic or hebrew languages). The scrollbar is then not on the right, but on the left, and then `clientLeft` also includes the scrollbar width.
+It becomes visible when the document is right-to-left (the operating system is in Arabic or Hebrew languages). The scrollbar is then not on the right, but on the left, and then `clientLeft` also includes the scrollbar width.
-In that case `clientLeft` in our example would be not `25`, but with the scrollbar width `25+16=41`:
+In that case, `clientLeft` would be not `25`, but with the scrollbar width `25 + 16 = 41`:

@@ -154,7 +152,7 @@ They include the content width together with paddings, but without the scrollbar

-On the picture above let's first consider `clientHeight`: it's easier to evaluate. There's no horizontal scrollbar, so it's exactly the sum of what's inside the borders: CSS-height `200px` plus top and bottom paddings (`2*20px`) total `240px`.
+On the picture above let's first consider `clientHeight`: it's easier to evaluate. There's no horizontal scrollbar, so it's exactly the sum of what's inside the borders: CSS-height `200px` plus top and bottom paddings (`2 * 20px`) total `240px`.
Now `clientWidth` -- here the content width is not `300px`, but `284px`, because `16px` are occupied by the scrollbar. So the sum is `284px` plus left and right paddings, total `324px`.
@@ -167,13 +165,13 @@ So when there's no padding we can use `clientWidth/clientHeight` to get the cont
## scrollWidth/Height
- Properties `clientWidth/clientHeight` only account for the visible part of the element.
-- Properties `scrollWidth/scrollHeight` also include the scrolled out (hidden) part:
+- Properties `scrollWidth/scrollHeight` also include the scrolled out (hidden) parts:

On the picture above:
-- `scrollHeight = 723` -- is the full inner height of the content area including the scrolled out part.
+- `scrollHeight = 723` -- is the full inner height of the content area including the scrolled out parts.
- `scrollWidth = 324` -- is the full inner width, here we have no horizontal scroll, so it equals `clientWidth`.
We can use these properties to expand the element wide to its full width/height.
@@ -182,7 +180,7 @@ Like this:
```js
// expand the element to the full content height
-element.style.height = element.scrollHeight + 'px';
+element.style.height = `${element.scrollHeight}px`;
```
```online
@@ -190,7 +188,7 @@ Click the button to expand the element:
text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
-
+
```
## scrollLeft/scrollTop
@@ -207,7 +205,7 @@ In other words, `scrollTop` is "how much is scrolled up".
Most geometry properties that are read-only, but `scrollLeft/scrollTop` can be changed, and the browser will scroll the element.
```online
-If you click the element below, the code `elem.scrollTop+=10` executes. That makes the element content scroll `10px` below.
+If you click the element below, the code `elem.scrollTop += 10` executes. That makes the element content scroll `10px` down.
Click Me 1 2 3 4 5 6 7 8 9
```
@@ -229,7 +227,7 @@ let elem = document.body;
alert( getComputedStyle(elem).width ); // show CSS width for elem
```
-Why we should use geometry properties instead? There are two reasons:
+Why should we use geometry properties instead? There are two reasons:
1. First, CSS width/height depend on another property: `box-sizing` that defines "what is" CSS width and height. A change in `box-sizing` for CSS purposes may break such JavaScript.
2. Second, CSS `width/height` may be `auto`, for instance for an inline element:
@@ -260,7 +258,7 @@ The element with text has CSS `width:300px`.
On a Desktop Windows OS, Firefox, Chrome, Edge all reserve the space for the scrollbar. But Firefox shows `300px`, while Chrome and Edge show less. That's because Firefox returns the CSS width and other browsers return the "real" width.
```
-Please note that the described difference are only about reading `getComputedStyle(...).width` from JavaScript, visually everything is correct.
+Please note that the described difference is only about reading `getComputedStyle(...).width` from JavaScript, visually everything is correct.
## Summary
@@ -271,7 +269,7 @@ Elements have the following geometry properties:
- `offsetWidth/offsetHeight` -- "outer" width/height of an element including borders.
- `clientLeft/clientTop` -- the distance from the left-upper outer corner to its left-upper inner corner. For left-to-right OS they are always the widths of left/top borders. For right-to-left OS the vertical scrollbar is on the left so `clientLeft` includes its width too.
- `clientWidth/clientHeight` -- the width/height of the content including paddings, but without the scrollbar.
-- `scrollWidth/scrollHeight` -- the width/height of the content including the scrolled out part. Also includes paddings, but not the scrollbar.
+- `scrollWidth/scrollHeight` -- the width/height of the content including the scrolled out parts. Also includes paddings, but not the scrollbar.
- `scrollLeft/scrollTop` -- width/height of the scrolled out part of the element, starting from its left-upper corner.
All properties are read-only except `scrollLeft/scrollTop`. They make the browser scroll the element if changed.
diff --git a/2-ui/1-document/09-size-and-scroll/metric-offset-parent.png b/2-ui/1-document/09-size-and-scroll/metric-offset-parent.png
index 5f1e58f9..01d2d000 100644
Binary files a/2-ui/1-document/09-size-and-scroll/metric-offset-parent.png and b/2-ui/1-document/09-size-and-scroll/metric-offset-parent.png differ
diff --git a/2-ui/1-document/09-size-and-scroll/metric-offset-parent@2x.png b/2-ui/1-document/09-size-and-scroll/metric-offset-parent@2x.png
index af62ebdc..125a91e1 100644
Binary files a/2-ui/1-document/09-size-and-scroll/metric-offset-parent@2x.png and b/2-ui/1-document/09-size-and-scroll/metric-offset-parent@2x.png differ
diff --git a/2-ui/1-document/10-size-and-scroll-window/article.md b/2-ui/1-document/10-size-and-scroll-window/article.md
index 0825b752..4a62f56c 100644
--- a/2-ui/1-document/10-size-and-scroll-window/article.md
+++ b/2-ui/1-document/10-size-and-scroll-window/article.md
@@ -4,8 +4,6 @@ How to find out the width of the browser window? How to get the full height of t
From the DOM point of view, the root document element is `document.documentElement`. That element corresponds to `` and has geometry properties described in the [previous chapter](info:size-and-scroll). For some cases we can use it, but there are additional methods and peculiarities important enough to consider.
-[cut]
-
## Width/height of the window
Properties `clientWidth/clientHeight` of `document.documentElement` is exactly what we want here:
@@ -55,7 +53,7 @@ let scrollHeight = Math.max(
document.body.clientHeight, document.documentElement.clientHeight
);
-alert('Full document width, with scrolled out part: ' + scrollHeight);
+alert('Full document height, with scrolled out part: ' + scrollHeight);
```
Why so? Better don't ask. These inconsistencies come from ancient times, not a "smart" logic.
diff --git a/2-ui/1-document/11-coordinates/article.md b/2-ui/1-document/11-coordinates/article.md
index 98758249..35ba15e1 100644
--- a/2-ui/1-document/11-coordinates/article.md
+++ b/2-ui/1-document/11-coordinates/article.md
@@ -9,8 +9,6 @@ Most JavaScript methods deal with one of two coordinate systems:
It's important to understand the difference and which type is where.
-[cut]
-
## Window coordinates: getBoundingClientRect
Window coordinates start at the left-upper corner of the window.
@@ -57,7 +55,7 @@ If we compare window coordinates versus CSS positioning, then there are obvious
But in CSS the `right` property means the distance from the right edge, and the `bottom` -- from the bottom edge.
-If we just look at the picture below, we can see that in JavaScript it is not so. All window coordinates are counted from the upper-left corner, including these ones.
+If we just look at the picture above, we can see that in JavaScript it is not so. All window coordinates are counted from the upper-left corner, including these ones.
```
## elementFromPoint(x, y) [#elementFromPoint]
diff --git a/2-ui/1-document/11-coordinates/head.html b/2-ui/1-document/11-coordinates/head.html
index efc6cd1c..0914f7f8 100644
--- a/2-ui/1-document/11-coordinates/head.html
+++ b/2-ui/1-document/11-coordinates/head.html
@@ -1,7 +1,11 @@
```
-There are 5 properties to describe CSS transitions:
+There are 4 properties to describe CSS transitions:
- `transition-property`
- `transition-duration`
@@ -262,9 +260,15 @@ But how to make the Bezier curve for a specific task? There are many tools. For
Timing function `steps(number of steps[, start/end])` allows to split animation into steps.
-Let's see that in an example with digits. We'll make the digits change not in a smooth, but in a discrete way.
+Let's see that in an example with digits.
-For that we split the animation into 9 steps:
+Here's a list of digits, without any animations, just as a source:
+
+[codetabs src="step-list"]
+
+We'll make the digits appear in a discrete way by making the part of the list outside of the red "window" invisible and shifting the list to the left with each step.
+
+There will be 9 steps, a step-move for each digit:
```css
#stripe.animate {
@@ -273,11 +277,11 @@ For that we split the animation into 9 steps:
}
```
-In action `step(9, start)`:
+In action:
[codetabs src="step"]
-The first argument of `steps` is the number of steps. The transform will be split into 9 parts (10% each). The time interval is divided as well: 9 seconds split into 1 second intervals.
+The first argument of `steps(9, start)` is the number of steps. The transform will be split into 9 parts (10% each). The time interval is automatically divided into 9 parts as well, so `transition: 9s` gives us 9 seconds for the whole animation – 1 second per digit.
The second argument is one of two words: `start` or `end`.
@@ -303,7 +307,7 @@ So the process would go like this:
- ...
- `9s` -- `-90%`
-In action `step(9, end)`:
+Here's `step(9, end)` in action (note the pause between the first digit change):
[codetabs src="step-end"]
diff --git a/3-animation/2-css-animations/step-list.view/index.html b/3-animation/2-css-animations/step-list.view/index.html
new file mode 100644
index 00000000..d7931f5e
--- /dev/null
+++ b/3-animation/2-css-animations/step-list.view/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
0123456789
+
+
+
diff --git a/3-animation/2-css-animations/step-list.view/style.css b/3-animation/2-css-animations/step-list.view/style.css
new file mode 100644
index 00000000..a934e834
--- /dev/null
+++ b/3-animation/2-css-animations/step-list.view/style.css
@@ -0,0 +1,9 @@
+#digit {
+ border: 1px solid red;
+ width: 1.2em;
+}
+
+#stripe {
+ display: inline-block;
+ font: 32px monospace;
+}
diff --git a/3-animation/3-js-animation/article.md b/3-animation/3-js-animation/article.md
index 99775934..f0f258c3 100644
--- a/3-animation/3-js-animation/article.md
+++ b/3-animation/3-js-animation/article.md
@@ -4,22 +4,19 @@ JavaScript animations can handle things that CSS can't.
For instance, moving along a complex path, with a timing function different from Bezier curves, or an animation on a canvas.
-[cut]
+## Using setInterval
-## setInterval
+An animation can be implemented as a sequence of frames -- usually small changes to HTML/CSS properties.
-From the HTML/CSS point of view, an animation is a gradual change of the style property. For instance, changing `style.left` from `0px` to `100px` moves the element.
-
-And if we increase it in `setInterval`, by making 50 small changes per second, then it looks smooth. That's the same principle as in the cinema: 24 or more frames per second is enough to make it look smooth.
+For instance, changing `style.left` from `0px` to `100px` moves the element. And if we increase it in `setInterval`, changing by `2px` with a tiny delay, like 50 times per second, then it looks smooth. That's the same principle as in the cinema: 24 or more frames per second is enough to make it look smooth.
The pseudo-code can look like this:
```js
-let delay = 1000 / 50; // in 1 second 50 frames
let timer = setInterval(function() {
if (animation complete) clearInterval(timer);
- else increase style.left
-}, delay)
+ else increase style.left by 2px
+}, 20); // change by 2px every 20ms, about 50 frames per second
```
More complete example of the animation:
@@ -52,15 +49,13 @@ Click for the demo:
[codetabs height=200 src="move"]
-## requestAnimationFrame
+## Using requestAnimationFrame
Let's imagine we have several animations running simultaneously.
-If we run them separately, each one with its own `setInterval(..., 20)`, then the browser would have to repaint much more often than every `20ms`.
+If we run them separately, then even though each one has `setInterval(..., 20)`, then the browser would have to repaint much more often than every `20ms`.
-Each `setInterval` triggers once per `20ms`, but they are independent, so we have several independent runs within `20ms`.
-
-These several independent redraws should be grouped together, to make it easier for the browser.
+That's because they have different starting time, so "every 20ms" differs between different animations. The intervals are not alignned. So we'll have several independent runs within `20ms`.
In other words, this:
@@ -72,19 +67,19 @@ setInterval(function() {
}, 20)
```
-...Is lighter than this:
+...Is lighter than three independent calls:
```js
-setInterval(animate1, 20);
-setInterval(animate2, 20);
+setInterval(animate1, 20); // independent animations
+setInterval(animate2, 20); // in different places of the script
setInterval(animate3, 20);
```
-There's one more thing to keep in mind. Sometimes when CPU is overloaded, or there are other reasons to redraw less often. For instance, if the browser tab is hidden, then there's totally no point in drawing.
+These several independent redraws should be grouped together, to make the redraw easier for the browser (and hence smoother for people).
-There's a standard [Animation timing](http://www.w3.org/TR/animation-timing/) that provides the function `requestAnimationFrame`.
+There's one more thing to keep in mind. Sometimes when CPU is overloaded, or there are other reasons to redraw less often (like when the browser tab is hidden), so we really shouldn't run it every `20ms`.
-It addresses all these issues and even more.
+But how do we know about that in JavaScript? There's a specification [Animation timing](http://www.w3.org/TR/animation-timing/) that provides the function `requestAnimationFrame`. It addresses all these issues and even more.
The syntax:
```js
@@ -418,7 +413,7 @@ Here's the animated "bouncing" text typing:
## Summary
-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.
+For animations that CSS can't handle well, or those that need tight control, JavaScript can help. JavaScript animations 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.
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.
diff --git a/4-frames-and-windows/01-popup-windows/article.md b/4-frames-and-windows/01-popup-windows/article.md
index a1839d6a..fa144f88 100644
--- a/4-frames-and-windows/01-popup-windows/article.md
+++ b/4-frames-and-windows/01-popup-windows/article.md
@@ -9,8 +9,6 @@ window.open('http://javascript.info/')
... And it will open a new window with given URL. Most modern browsers are configured to open new tabs instead of separate windows.
-[cut]
-
## Popup blocking
Popups exist from really ancient times. The initial idea was to show another content without closing the main window. As of now, there are other ways to do that: JavaScript is able to send requests for server, so popups are rarely used. But sometimes they are still handy.
diff --git a/4-frames-and-windows/03-cross-window-communication/article.md b/4-frames-and-windows/03-cross-window-communication/article.md
index 15394969..d9b9247c 100644
--- a/4-frames-and-windows/03-cross-window-communication/article.md
+++ b/4-frames-and-windows/03-cross-window-communication/article.md
@@ -4,8 +4,6 @@ The "Same Origin" (same site) policy limits access of windows and frame to each
The idea is that if we have two windows open: one from `john-smith.com`, and another one is `gmail.com`, then we wouldn't want a script from `john-smith.com` to read our mail.
-[cut]
-
## Same Origin [#same-origin]
Two URLs are said to have the "same origin" if they have the same protocol, domain and port.
@@ -27,7 +25,7 @@ If we have a reference to another window (a popup or iframe), and that window co
If it comes from another origin, then we can only change its location. Please note: not *read* the location, but *modify* it, redirect it to another place. That's safe, because the URL may contain sensitive parameters, so reading it from another origin is prohibited, but changing is not.
-Also such windows windows may exchange messages. Soon about that later.
+Also such windows may exchange messages. Soon about that later.
````warn header="Exclusion: subdomains may be same-origin"
diff --git a/4-frames-and-windows/06-clickjacking/article.md b/4-frames-and-windows/06-clickjacking/article.md
index 66b918e1..bcffc3fd 100644
--- a/4-frames-and-windows/06-clickjacking/article.md
+++ b/4-frames-and-windows/06-clickjacking/article.md
@@ -4,22 +4,20 @@ The "clickjacking" attack allows an evil page to click on a "victim site" *on be
Many sites were hacked this way, including Twitter, Facebook, Paypal and other sites. They are all fixed, of course.
-[cut]
-
## The idea
The idea is very simple.
Here's how clickjacking was done with Facebook:
-1. A visitor is lured to the evil page. No matter how.
-2. The page has a harmlessly-looking link on it (like "get rich now" or "click here, very funny" and so on).
+1. A visitor is lured to the evil page. It doesn't matter how.
+2. The page has a harmless-looking link on it (like "get rich now" or "click here, very funny").
3. Over that link the evil page positions a transparent `