mirror of
https://github.com/bendtherules/UiQuestions.git
synced 2026-08-18 22:02:42 +00:00
element-properties - Add firstChild + nextSibling section
This commit is contained in:
@@ -23,7 +23,7 @@ ele.tagName // "IMG"
|
|||||||
|
|
||||||
:::note Text nodes don't have `tagName`
|
:::note Text nodes don't have `tagName`
|
||||||
|
|
||||||
Text nodes are not element, so they don't have any tagName. To identify the type of node, use `.nodeType`. For text nodes, `nodeType` is `3`- same as the constant `Node.TEXT_NODE`.
|
Text nodes are not element, so they don't have any tagName. To identify the type of node, use `.nodeType` property. For text nodes, `nodeType` is `3` - same as the constant `Node.TEXT_NODE`.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ container.childNodes // [text, div, text]
|
|||||||
Read more about [other types of nodes](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType) and how [whitespace works in html](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace).
|
Read more about [other types of nodes](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType) and how [whitespace works in html](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace).
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### 2. .children
|
### 2. children
|
||||||
|
|
||||||
`Element.children: HTMLCollection`
|
`Element.children: HTMLCollection`
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ for (let i = 0; i < children.length; i++) {
|
|||||||
|
|
||||||
<MDN title="children" url="https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/children" />
|
<MDN title="children" url="https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/children" />
|
||||||
|
|
||||||
### 3. .childNodes
|
### 3. childNodes
|
||||||
|
|
||||||
`Element.childNodes: NodeList`
|
`Element.childNodes: NodeList`
|
||||||
|
|
||||||
@@ -129,6 +129,71 @@ childNodes // NodeList [text, span, text]
|
|||||||
|
|
||||||
<MDN title="childNodes" url="https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes" />
|
<MDN title="childNodes" url="https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes" />
|
||||||
|
|
||||||
|
### 4. firstChild + nextSibling
|
||||||
|
|
||||||
|
`Element.firstChild: Node`
|
||||||
|
|
||||||
|
|
||||||
|
This property returns the element's **first child** node in the tree. If the node has no children, then it returns `null`.
|
||||||
|
|
||||||
|
`Element.nextSibling: Node`
|
||||||
|
|
||||||
|
This property returns the node immediately **after the current one** in their parent's childNodes.
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
<div id="A">
|
||||||
|
<div id="B"/>
|
||||||
|
<div id="C"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
var eleA = document.getElementByID("A")
|
||||||
|
|
||||||
|
var eleB = eleA.firstChild // <div id="B">
|
||||||
|
var eleC = eleB.nextSibling // <div id="C"/>
|
||||||
|
eleC.nextSibling // null
|
||||||
|
```
|
||||||
|
|
||||||
|
There is also a similar `previousSibling` property, which returns the previous node. Also, there are element-only variant for all these properties like `firstElementChild`, `nextElementSibling`, etc.
|
||||||
|
|
||||||
|
<Accordion title="Why is this useful?">
|
||||||
|
|
||||||
|
:::note Easier traversal
|
||||||
|
|
||||||
|
This allows accessing the DOM tree in [Left-child right-sibling](https://en.wikipedia.org/wiki/Left-child_right-sibling_binary_tree) (LCRS) form, which is more memory efficient for usual traversal.
|
||||||
|
|
||||||
|
#### How do you implement **dom traversal**?
|
||||||
|
|
||||||
|
The typical approach is to use a queue, push all children to the queue, pop them one-by-one and visit them. This requires **extra memory** because of the queue data structure which holds all the *next items to visit*.
|
||||||
|
But with the LCRS form, you always have access to the next item **without using extra space**. If current element has child, visit `.firstChild`. Then visit next node using `.nextSibling`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// 1. Typical approach
|
||||||
|
var queue = [root]
|
||||||
|
while (queue.length > 0) {
|
||||||
|
const item = queue.shift();
|
||||||
|
console.log(item);
|
||||||
|
if (item.hasChildNodes()) {
|
||||||
|
queue = Array.from(item.childNodes).concat(queue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. LCRS approach
|
||||||
|
function traverse(item) {
|
||||||
|
if (item === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(item);
|
||||||
|
traverse(item.firstChild)
|
||||||
|
traverse(item.nextSibling)
|
||||||
|
}
|
||||||
|
traverse(root.firstChild)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
</Accordion>
|
||||||
|
|
||||||
|
|
||||||
<!-- ## Content - html, text
|
<!-- ## Content - html, text
|
||||||
|
|
||||||
## Traversal (and ientification)
|
## Traversal (and ientification)
|
||||||
|
|||||||
Reference in New Issue
Block a user