minor
This commit is contained in:
parent
6d1fa5de73
commit
d63c27bcc6
7 changed files with 108 additions and 83 deletions
|
@ -8,15 +8,25 @@ libs:
|
|||
|
||||
The backbone of an HTML document are tags.
|
||||
|
||||
According to Document Object Model (DOM), every HTML-tag is an object. Nested tags are called "children" of the enclosing one.
|
||||
According to Document Object Model (DOM), every HTML-tag is an object. Nested tags are "children" of the enclosing one. The text inside a tag it is an object as well.
|
||||
|
||||
The text inside a tag it is an object as well.
|
||||
All these objects are accessible using JavaScript, we can use them to modify the page.
|
||||
|
||||
All these objects are accessible using JavaScript.
|
||||
For example, `document.body` is the object representing `<body>` tag.
|
||||
|
||||
Running this code will make the `<body>` red for 3 seconds:
|
||||
|
||||
```js run
|
||||
document.body.style.background = 'red'; // make the background red
|
||||
|
||||
setTimeout(() => document.body.style.background = '', 3000); // return back
|
||||
```
|
||||
|
||||
That was just a glimpse of DOM power. Soon we'll learn more ways to manipulate DOM, but first we need to know about its structure.
|
||||
|
||||
## An example of DOM
|
||||
|
||||
For instance, let's explore the DOM for this document:
|
||||
Let's start with the following simple docment:
|
||||
|
||||
```html run no-beautify
|
||||
<!DOCTYPE HTML>
|
||||
|
@ -44,7 +54,9 @@ drawHtmlTree(node1, 'div.domtree', 690, 320);
|
|||
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: `<html>` is at the root, then `<head>` and `<body>` are its children, etc.
|
||||
Every tree node is an object.
|
||||
|
||||
Tags are *element nodes* (or just elements), they form the tree structure: `<html>` is at the root, then `<head>` and `<body>` 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,7 +67,7 @@ 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 `<head>` tag contains some spaces before `<title>`, and that text becomes a `#text` node (it contains a newline and some spaces only).
|
||||
Spaces and newlines -- are totally valid characters, like letters and digits. They form text nodes and become a part of the DOM. So, for instance, in the example above the `<head>` tag contains some spaces before `<title>`, 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 `<head>` are ignored for historical reasons,
|
||||
|
@ -78,15 +90,14 @@ let node2 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,
|
|||
drawHtmlTree(node2, 'div.domtree', 690, 210);
|
||||
</script>
|
||||
|
||||
```smart header="Edge spaces and in-between empty text are usually hidden in tools"
|
||||
```smart header="Spaces at string start/end and space-only text nodes are usually hidden in tools"
|
||||
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 how it is shown (in most cases).
|
||||
Developer tools save screen space this way.
|
||||
|
||||
On further DOM pictures we'll sometimes omit them where they are irrelevant, to keep things short.
|
||||
On further DOM pictures we'll sometimes omit them when they are irrelevant. Such spaces usually do not affect how the document is displayed.
|
||||
```
|
||||
|
||||
|
||||
## Autocorrection
|
||||
|
||||
If the browser encounters malformed HTML, it automatically corrects it when making DOM.
|
||||
|
@ -148,7 +159,9 @@ You see? The `<tbody>` appeared out of nowhere. You should keep this in mind whi
|
|||
|
||||
## Other node types
|
||||
|
||||
Let's add more tags and a comment to the page:
|
||||
There are some other node types besides elements and text nodes.
|
||||
|
||||
For example, comments:
|
||||
|
||||
```html
|
||||
<!DOCTYPE HTML>
|
||||
|
@ -174,7 +187,7 @@ let node6 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,
|
|||
drawHtmlTree(node6, 'div.domtree', 690, 500);
|
||||
</script>
|
||||
|
||||
Here we see a new tree node type -- *comment node*, labeled as `#comment`.
|
||||
We can see here a new tree node type -- *comment node*, labeled as `#comment`, between two text nodes.
|
||||
|
||||
We may think -- why is a comment 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.
|
||||
|
||||
|
@ -195,8 +208,6 @@ There are [12 node types](https://dom.spec.whatwg.org/#node). In practice we usu
|
|||
|
||||
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 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 the browser developer tools and switch to the Elements tab.
|
||||
|
@ -225,10 +236,12 @@ The best way to study them is to click around. Most values are editable in-place
|
|||
|
||||
## Interaction with console
|
||||
|
||||
As we explore the DOM, we also may want to apply JavaScript to it. Like: get a node and run some code to modify it, to see the result. Here are few tips to travel between the Elements tab and the console.
|
||||
As we work the DOM, we also may want to apply JavaScript to it. Like: get a node and run some code to modify it, to see the result. Here are few tips to travel between the Elements tab and the console.
|
||||
|
||||
- Select the first `<li>` in the Elements tab.
|
||||
- Press `key:Esc` -- it will open console right below the Elements tab.
|
||||
For the start:
|
||||
|
||||
1. Select the first `<li>` in the Elements tab.
|
||||
2. Press `key:Esc` -- it will open console right below the Elements tab.
|
||||
|
||||
Now the last selected element is available as `$0`, the previously selected is `$1` etc.
|
||||
|
||||
|
@ -236,9 +249,11 @@ We can run commands on them. For instance, `$0.style.background = 'red'` makes t
|
|||
|
||||

|
||||
|
||||
From the other side, if we're in console and have a variable referencing a DOM node, then we can use the command `inspect(node)` to see it in the Elements pane.
|
||||
That's how to get a node from Elements in Console.
|
||||
|
||||
Or we can just output it in the console and explore "at-place", like `document.body` below:
|
||||
There's also a road back. If there's a variable referencing a DOM node, then we can use the command `inspect(node)` in Console to see it in the Elements pane.
|
||||
|
||||
Or we can just output DOM-node in the console and explore "at-place", like `document.body` below:
|
||||
|
||||

|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ libs:
|
|||
|
||||
The DOM allows us to do anything with elements and their contents, but first we need to reach the corresponding DOM object.
|
||||
|
||||
All operations on the DOM start with the `document` object. From it we can access any node.
|
||||
All operations on the DOM start with the `document` object. That's the main "entry point" to DOM. From it we can access any node.
|
||||
|
||||
Here's a picture of links that allow for travel between DOM nodes:
|
||||
|
||||
|
@ -86,9 +86,9 @@ For instance, here `<body>` has children `<div>` and `<ul>` (and few blank text
|
|||
</html>
|
||||
```
|
||||
|
||||
...And all descendants of `<body>` are not only direct children `<div>`, `<ul>` but also more deeply nested elements, such as `<li>` (a child of `<ul>`) and `<b>` (a child of `<li>`) -- the entire subtree.
|
||||
...And descendants of `<body>` are not only direct children `<div>`, `<ul>` but also more deeply nested elements, such as `<li>` (a child of `<ul>`) and `<b>` (a child of `<li>`) -- the entire subtree.
|
||||
|
||||
**The `childNodes` collection provides access to all child nodes, including text nodes.**
|
||||
**The `childNodes` collection lists all child nodes, including text nodes.**
|
||||
|
||||
The example below shows children of `document.body`:
|
||||
|
||||
|
@ -182,30 +182,34 @@ Please, don't. The `for..in` loop iterates over all enumerable properties. And c
|
|||
|
||||
## Siblings and the parent
|
||||
|
||||
*Siblings* are nodes that are children of the same parent. For instance, `<head>` and `<body>` are siblings:
|
||||
*Siblings* are nodes that are children of the same parent.
|
||||
|
||||
For instance, here `<head>` and `<body>` are siblings:
|
||||
|
||||
```html
|
||||
<html>
|
||||
<head>...</head><body>...</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
- `<body>` is said to be the "next" or "right" sibling of `<head>`,
|
||||
- `<head>` is said to be the "previous" or "left" sibling of `<body>`.
|
||||
|
||||
The next sibling is is `nextSibling`, and the previous one is `previousSibling`.
|
||||
|
||||
The parent is available as `parentNode`.
|
||||
|
||||
The next node in the same parent (next sibling) is `nextSibling`, and the previous one is `previousSibling`.
|
||||
So all these tests are truthy:
|
||||
|
||||
For instance:
|
||||
```js
|
||||
// parent of <body> is <html>
|
||||
alert( document.body.parentNode === document.documentElement ); // true
|
||||
|
||||
```html run
|
||||
<html><head></head><body><script>
|
||||
// HTML is "dense" to evade extra "blank" text nodes.
|
||||
// after <head> goes <body>
|
||||
alert( document.head.nextSibling ); // HTMLBodyElement
|
||||
|
||||
// parent of <body> is <html>
|
||||
alert( document.body.parentNode === document.documentElement ); // true
|
||||
|
||||
// after <head> goes <body>
|
||||
alert( document.head.nextSibling ); // HTMLBodyElement
|
||||
|
||||
// before <body> goes <head>
|
||||
alert( document.body.previousSibling ); // HTMLHeadElement
|
||||
</script></body></html>
|
||||
// before <body> goes <head>
|
||||
alert( document.body.previousSibling ); // HTMLHeadElement
|
||||
```
|
||||
|
||||
## Element-only navigation
|
||||
|
@ -235,12 +239,12 @@ alert( document.documentElement.parentNode ); // document
|
|||
alert( document.documentElement.parentElement ); // null
|
||||
```
|
||||
|
||||
In other words, the `documentElement` (`<html>`) is the root node. Formally, it has `document` as its parent. But `document` is not an element node, so `parentNode` returns it and `parentElement` does not.
|
||||
The reason is that root node `document.documentElement` (`<html>`) has `document` as its parent. But `document` is not an element node, so `parentNode` returns it and `parentElement` does not.
|
||||
|
||||
This loop travels up from an arbitrary element `elem` to `<html>`, but not to the `document`:
|
||||
This detail may be useful when we want to travel up from an arbitrary element `elem` to `<html>`, but not to the `document`:
|
||||
```js
|
||||
while(elem = elem.parentElement) {
|
||||
alert( elem ); // parent chain till <html>
|
||||
while(elem = elem.parentElement) { // go up till <html>
|
||||
alert( elem );
|
||||
}
|
||||
```
|
||||
````
|
||||
|
|
|
@ -11,15 +11,15 @@ table.getElementsByTagName('label')
|
|||
// or
|
||||
document.querySelectorAll('#age-table label')
|
||||
|
||||
// 3. The first td in that table (with the word "Age").
|
||||
// 3. The first td in that table (with the word "Age")
|
||||
table.rows[0].cells[0]
|
||||
// or
|
||||
table.getElementsByTagName('td')[0]
|
||||
// or
|
||||
table.querySelector('td')
|
||||
|
||||
// 4. The form with the name "search".
|
||||
// assuming there's only one element with name="search"
|
||||
// 4. The form with the name "search"
|
||||
// assuming there's only one element with name="search" in the document
|
||||
let form = document.getElementsByName('search')[0]
|
||||
// or, form specifically
|
||||
document.querySelector('form[name="search"]')
|
||||
|
@ -29,8 +29,7 @@ form.getElementsByTagName('input')[0]
|
|||
// or
|
||||
form.querySelector('input')
|
||||
|
||||
// 6. The last input in that form.
|
||||
// there's no direct query for that
|
||||
let inputs = form.querySelectorAll('input') // search all
|
||||
inputs[inputs.length-1] // take last
|
||||
// 6. The last input in that form
|
||||
let inputs = form.querySelectorAll('input') // find all inputs
|
||||
inputs[inputs.length-1] // take the last one
|
||||
```
|
||||
|
|
|
@ -6,12 +6,12 @@ importance: 4
|
|||
|
||||
Here's the document with the table and form.
|
||||
|
||||
How to find?
|
||||
How to find?...
|
||||
|
||||
1. The table with `id="age-table"`.
|
||||
2. All `label` elements inside that table (there should be 3 of them).
|
||||
3. The first `td` in that table (with the word "Age").
|
||||
4. The `form` with the name `search`.
|
||||
4. The `form` with `name="search"`.
|
||||
5. The first `input` in that form.
|
||||
6. The last `input` in that form.
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ Pseudo-classes in the CSS selector like `:hover` and `:active` are also supporte
|
|||
|
||||
The call to `elem.querySelector(css)` returns the first element for the given CSS selector.
|
||||
|
||||
In other words, the result is the same as `elem.querySelectorAll(css)[0]`, but the latter is looking for *all* elements and picking one, while `elem.querySelector` just looks for one. So it's faster and shorter to write.
|
||||
In other words, the result is the same as `elem.querySelectorAll(css)[0]`, but the latter is looking for *all* elements and picking one, while `elem.querySelector` just looks for one. So it's faster and also shorter to write.
|
||||
|
||||
## matches
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue