What were some methods that we could use to add or get rid of elements from the DOM →
.removeChild(childNodeToRemove)
- removes a child node from the DOM and returns it (node still exists in memory, but is no longer in DOM tree).appendChild(nodeToAppend)
- puts node at end of list of this node's child nodes and returns the appended node.insertBefore(nodeToInsert, beforeThisNode)
- inserts node before the node given as child of current node and returns the inserted node.replaceChild(nodeToInsert, nodeToReplace)
- replaces a child of the current node with the nodeToInsert and returns the replaced nodeWe didn't have a chance to try this previously… so let's check out another sample page. Starting with:
const content = document.getElementById('content');
const paragraphs = document.getElementsByTagName('p');
Move the 3rd paragraph between the first two. →
const inserted = content.insertBefore(paragraphs[2], paragraphs[1]);
Now, instead of just inserting before, let's replace paragraph "Two" with paragraph "Three": →
const replaced = content.replaceChild(paragraphs[2], paragraphs[1]);
We also looked at removing elements with removeChild. This was our first attempt:
const div = document.getElementById('content');
const p = div.getElementsByTagName('p');
for(let i = 0; i < p.length; i++) {
div.removeChild(p[i]);
}
But… what happened? →
There was an element left over because we were editing a live data structure. How did we fix this? →
To get around this issue, we could:
while (div.firstChild) {
div.removeChild(div.firstChild);
}
const copy = Array.prototype.slice.call(p, 0)
copy.forEach(function(ele) {
div.removeChild(ele)
});
The following Node property and methods allow you to read and / or modify that Node's content:
nodeValue - represents content of text and comment nodes, null otherwise
// assuming we have an element_node, and we know its first child is a text element
console.log(node.firstChild.nodeValue);
node.firstChild.nodeValue = 'new text';
textContent - the text content of the node and all of its descendants (!)
const text = element.textContent;
element.textContent = "this is some sample text";
There are other properties similar to textContent
, such as innerHTML
(which includes markup) and innerText
which is aware of styling (for example, ignores hidden elements).
What do the following lines of code represent / do based on the markup below? →
<div id="content">
<p>One</p>
<p class="cta">Two</p>
<p class="cta">Three</p>
</div>
document.body.textContent
document.body.innerHTML
document.body.nodeValue
const p = document.getElementsByTagName('p')[0]
p.firstChild.nodeValue
p.firstChild.nodeValue = 'Surprised?'
p.textContent = 'Maybe not.'
The following methods actually create new Nodes!
Note… that they're called on the built-in document
object, not on Node
or an instance of node
.
Replace each paragraph element with text that says "this was a paragraph".
<div id="content">
<p>One</p>
<p class="cta">Two</p>
<p class="cta">Three</p>
</div>
const div = document.getElementById('content');
const p = div.getElementsByTagName('p');
for(let i = p.length - 1; i >= 0; i--) {
div.replaceChild(
document.createTextNode("this was a paragraph"),
p[i]);
}
Instead of just a text node, replace each paragraph with an h1
(a header). The text should remain the same. →
const div = document.getElementById('content');
const p = div.getElementsByTagName('p');
for(let i = p.length - 1; i >= 0; i--) {
const header = document.createElement("h1");
const content = document.createTextNode(p[i].textContent);
header.appendChild(content);
div.replaceChild(header, p[i]);
}
Creating each element and adding a child was a bit of a drag…
The book uses a convenience method to add an element and an arbitrary number of child elements.
It acts like this: elt(type, [, child1, ..., child2);
→
type
How would we create this? →
A potential implementation… →
function elt(type) {
const ele = document.createElement(type);
// start at 1 or else we'll get the type argument!
for (let i = 1; i < arguments.length; i++) {
let child = arguments[i];
if (typeof child === "string") {
child = document.createTextNode(child);
}
ele.appendChild(child);
}
return ele;
}
const ul = elt('ul', elt('li', 'item one'), elt('li', 'item two'));
document.body.appendChild(ul);