JS DOM - 02.02 - DOM Basics

DOM modification is key in creating “live” pages from js by creating new elements and modify the existing page content.

When a HTML file is parsed into DOM, the nodes will be JavaScript objects that have properties and methods attached to them. These are the primary tools we are going to use to manipulate our webpage with js

Basic DOM Manipulation

To manipulate an element inside the DOM, first it needs to be selected and store a reference to it in a variable. This stored reference can be manipulated using properties and methods available to it.

const link = document.querySelector("a");
link.textContent = "Adding text to the anchor tag";
link.href = "https://developer.mozilla.org";

Creating an element

Two methods are there to create a new element

  • documnet.createElement(tag) creates a new element node with given tag.
  • document.createTextNode(text) creates a new text node with the given text
let div = document.createElement('div');
let textNode = documnet.createTextNode('Hi');
document.createElement(tagName, [options])

const div = document.createElement("div")

Creates a new element of tagName tag type. [options] to add some optional parameters to the function.

This function does not put the new element into the DOM - it creates it in memory. It can be manipulated by adding style, classes, ids, text, etc before placing it on the page.

create a div, set a class, adding inner HTML and text

let div = document.createElement('div');

div.className = "alert";

div.innerHTML = "<strong>Hi there</strong> important message.";

inserting element into DOM

document.body.append(div); appending a div directly to the body tag of document. Here are more insertion methods, they specify different places where to insert:

node.append(...nodes or strings)
// append nodes or strings at the end of `node`,

node.prepend(...nodes or strings)
// insert nodes or strings at the beginning of `node`,

node.before(...nodes or strings)
// insert nodes or strings before `node`,

node.after(...nodes or strings)
// insert nodes or strings after `node`,

node.replaceWith(...nodes or strings)
// replaces `node` with the given nodes or strings.

These methods can only be used to insert DOM nodes or text but not HTML as it will get converted to text including <>

’elem.insertAdjacentHTML(where, html)'

To insert HTML string as HTML with all tags similar to elem.innerHTML another method can be used

elem.insertAdjacentHTML(where, html)

// the first parameter where is a code word, it must be one of this.
- "beforebegin" // insert `html` immediately before `elem`, similar to begin
- "afterbegin" // insert `html` into `elem`, at the beginning, similar to prepend
- "beforeend" // insert `html` into `elem`, at the end, similar to append
- "afterend" // insert `html` immediately after `elem`, similar to after.

These placements work exactly as previous four methods but for HTML strings.

<div id = "div"></div>

<script>
	div.insertAdjacentHTML('beforebegin', '<p>Hello</p>');
	div.insertAdjacentHTML('afterend', '<p>Bye</p>');
</script>

// will become
<p>Hello</p>
<div id = 'div'></div>
<p>Bye</p>

Redoing the previous div insertion done using innerHTML

<script>
	document.body.insertAdjacentHTML("afterbegin", <div class='alert'><strong>Hi there</strong> important message.</div>)

</script>

[[2.2 modifying Practice#Insert the HTML in the list|Another example]]


Node removal ’node.remove()'

To make message disappear after a second

<script>
	let div = document.createElement('div');
	div.className = "alert";
	div.innerHTML = "<strong>Hi there</strong> important message.";
	documnet.body.append(div);

	setTimeOut( () => div.remove(), 1000 );
</script>

Clearing the list items from list

<ol id='elem'>
	<li>Hello</li>
	<li>World</li>
</ol>

<script>
	// function clear(elem) {  this wont work
	//	for (let i=0; i < elem.childNodes.length; i++) {
	//		elem.childNodes[i].remove(); }	}

	function clear(elem) {  // removing all child
		while (elem.firstChild) {
			elem.firstChild.remove();
			}
		}
	function clear(elem) {  // clearing innerHTML
		elem.innerHTML = '';
		}
		
	clear(elem); // clear the list
</script>

Please note: if we want to move an element to another place – there’s no need to remove it from the old one. All insertion methods automatically remove the node from the old place.


cloning nodes ‘cloneNode(deep)’

The call elem.cloneNode(true) creates a “deep” clone of the element – with all attributes and sub elements. If we call elem.cloneNode(false), then the clone is made without child elements.

<div class = 'alert'><strong>Hi there</strong> important message.</div>

<script>
	let div2 = div.cloneNode(true);  // cloning div node
	
	div2.querySelector('strong').innerHTML = 'Bye there';
	// replacing the text within the strong html tag
	
	div.after(div2);  // adding new div after old div
</script>

Making multiple nodes and adding it to DOM

<ul id='ul'></ul>

<script>
	function getListContent(){
		let result = [];
		
		for( let i =1; i<=3; i++) {
			let li = document.createElement('li');
			li.append(i);  // add number string to list item 
			result.push(li);  // push list item to result array
			}
			return result;
		}
	ul.append(...getListContent() );
	// unpack array using rest parameter, append all to ul 
</script>

old school methods for DOM manipulation

  • parent.appendChild(node)
  • parent.insertBefore(node, nextSibling)
  • parent.removeChild(node)
  • parent.replaceChild(newElem, node)

Nowadays, there’s no reason to use them, as modern methods, such as appendprependbeforeafterremovereplaceWith, are more flexible.

parentNode.appendChild(childNode)
// appends childNode as last child of parentNode

parentNode.insertBefore(newNode, referenceNode)
// inserts newNode into parentNode before referenceNode
parentNode.removeChild(child)
// removes child from parentNode and returns a reference to child.