DEV Community

loading...
Cover image for DOM Explained (somewhat πŸ˜†) & Modifying it With Vanilla JavaScript

DOM Explained (somewhat πŸ˜†) & Modifying it With Vanilla JavaScript

Jacob Evans
FullStack Software Engineer @ Cloudflare | Air Force Veteran | Hardware Enthusiast | Outdoorsman | OSS Enthusiast & Contributor
・4 min read

tl;dr I made this article with HTML and use it to explain DOM, window, document and how to manipulate/interface with those things with JavaScript.

EDIT: The article is unpolished. If anything is unclear or you have feedback, please leave a comment or say something on to me on Twitter

What is the DOM?

The DOM essentially, is a representation of a document as a tree structure. The parts of the tree structure branches are nodes, those nodes contain objects. Let's take a moment to get an example of what something like this might look like, and open up the browser console and you can copy & paste then into the console document.getElementsByTagName('abbr') what you get back should look something like HTMLCollection[abbr] now what is this? Well, it is an array-like (so not an array exactly) "collection" of the elements or nodes. This is an example of many elements being found coming back but we only have one "abbr" Element but if we were to pass in document.getElementsByTagName('code') we would get a large collection coming back because I am using that tag A ALOT lol.

Let's dig a little into grabbing a specific Element and utilizing some Node and Element methods. Alright, let's get back into the console, this time we will be assigning a variable to a specific element. const ele = document.getElementById('dom-abbr-id') don't worry I added an id to this article πŸ˜† (don't leave console). Hmmm, What can we do with this πŸ€”... Well, anything really but for starters let us take a look at moving around a bit. Still in the console ele.previousSibling oh Snap! we got "The" but that's not an element, no but let's find out what the "previousSiblingElement" is for our little experiment. el.previousElementSibling Oh, Interesting! what happen this time, since we were getting an element sibling, it ended up being the `h1` which in my HTML is the `h1` tag containing the header right before the DOM abbreviation element. We will talk more about what we can do with these elements once we get them.

Children & Siblings


Now I think we will make some lists and use some child and sibling methods.
  • First Item
  • Second Item
  • Third Item

alright, now we have the list... I think we can try some new document methods. So in the console we are going to type

// This gets ul element we want in this
// document I added the id
const ul = document.getElementById('ul-test') 
// Let's see what children of this element are? 
ul.childElementCount // 3
// Whoa we have three things in the list!
// The children are the elements in ul element... 
// I wonder if we can get another HTMLCollection! 
ul.children // HTMLCollection(3) [li, li, li]
Enter fullscreen mode Exit fullscreen mode

I wonder what siblings of this ul element would look like?

// Next we can get the next Element from `ul`
ul.nextElementSibling 
\<p> 
"alright, now we have the list... 
I think we can try some new document methods. 
So in the console, we are going to type" 
</p>\
Enter fullscreen mode Exit fullscreen mode

Awesome it looks like the sibling element that was next was the following sentence after the ul element! So cool! 😎 So it must be on the Element API of the document.
So there is still the none element sibling, let's go ahead and see what that is now. This one should behave differently since it is on the Node API, what will be getting next? πŸ˜†

ul.nextSibling
// #text
ul.nextSibling.nextSibling 
// This will also return that next paragraph Element!
// To see kind of an overview of all the Nodes on ul let's use
// the Node interface for childNodes
el.childNodes // NodeList(7) [text, li, text, li, text, li, text] 
Enter fullscreen mode Exit fullscreen mode

So what is that #text node? Well, I couldn't think of a better way to explain it then how MDN already has...
"In the above example, #text nodes are inserted in the DOM where whitespace occurs between tags (i.e. after the closing tag of an element and before the opening tag of the next)." - MDN

Using Nodes & Elements


I will attempt to use Document, Nodes, and Elements APIs to modify the document. I think we can maybe remove all the code elements, replace certain words, and replace all pre HTML tags. πŸ™‚
// Run this in console on this page 🀩
function modifyDOM() {
const code = document.getElementsByTagName('code')
const elms = document.getElementsByTagName('*')

for(ele of code) {
ele.remove()
 }

for(ele of elms) {
if(ele.tagName === 'PRE') {
const newEle = document.createElement('p');
newEle.innerHTML = '<b>HELLO WORLD!!!!!</b>';
ele.parentNode.replaceChild(newEle, ele);
  }

 }
document.body.innerHTML = document.body.innerHTML.replace(/nodes/g, '<b>REPLACED NODES</b>');
document.body.innerHTML = document.body.innerHTML.replace(/example/g, '<b>REPLACED EXAMPLE</b>');
}
// Then invoke the function in console and watch the page change πŸ₯³
modifyDOM()
Enter fullscreen mode Exit fullscreen mode

Don't worry all the changes are temporary all you need to do, to undo them is refresh the page πŸ˜…

Discussion (0)