DOM Explained (somewhat 😆) & Modifying it With Vanilla JavaScript
Tags: javascript, webdev, html, tutorial
Published: 2019-11-16 23:04:51

<article>
  <header>
    <i>
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. 
    </i>
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](https://twitter.com/JacobMGEvans) 
  </header>
  <main>
    
<p> <h1>What is the DOM?</h1> The <abbr id="dom-abbr-id" title="Document Object Model">DOM</abbr> 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 <code> document.getElementsByTagName('abbr')</code> what you get back should look something like <code>HTMLCollection[abbr]</code> 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 <code>document.getElementsByTagName('code')</code> we would get a large collection coming back because I am using that tag A ALOT lol. </p> 
<p> 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. <code>const ele = document.getElementById('dom-abbr-id') </code> 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<code> ele.previousSibling </code> 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. <code>
el.previousElementSibling </code> 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. 
</p>
<p>
<h2> Children & Siblings </h2>
Now I think we will make some lists and use some child and sibling methods. 
<ul id='ul-test'>
<li>First Item</li>
<li>Second Item</li>
<li>Third Item</li>
</ul>
alright, now we have the list... I think we can try some new document methods. So in the console we are going to type 
```javascript
// 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]
```
I wonder what siblings of this `ul` element would look like?
```javascript
// 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>\
```
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](https://developer.mozilla.org/en-US/docs/Web/API/NonDocumentTypeChildNode/nextElementSibling). 
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](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling), what will be getting next? 😆
```javascript
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] 
```
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
</p>

<p><h2>Using Nodes & Elements</h2>
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. 🙂
```javascript
// 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()
```
Don't worry all the changes are temporary all you need to do, to undo them is refresh the page 😅
</p>
  </main>
</article>