What is the DOM
So just what is the Document Object Model? Well if you have read any explanations or tutorials, you’ll know it is filled with endless jargon and verbiage which sounds awfully confusing. I could tell you something like, “The DOM is an application programming interface which operates with well formed standards based HTML and associated components, and…” but these are just buzzwords. The concept of the DOM is actually fairly straightforward, let’s go through it one step at a time.
What is the Document?
Web Page: The Document portion of DOM is referring to the page. When you view an HTML file simply in notepad, or in an IDE with nice syntax highlighting, or through a web browser to see the rendered result, all instances are simply the Document. The page itself is the document.
What are Objects?
Pieces: The Object portion of the DOM is simply a thing, which may or may not contain something inside of it. When we look at a piece of HTML, and say, look at the head section, or the body section, or maybe even an unordered list or p tag – what we’re referring to are objects of the page. They are objects of the DOM.
What is the Model?
Agreed Upon Terms: The Model is a bit more generic in meaning, it is not a concrete thing, it is an idea. The Model is like the data or business abstraction of the Document. When we talk about all of the objects on the page in terms of specific HTML tags, nodes, child nodes, and parent nodes, we are speaking the same language. The model is the agreed upon set of terms and standards that describe exactly how we can interact with the pieces of a webpage. These rules work with any webpage there is, this is the importance of it.
What you can do with the DOM
- Get the third paragraph
- Get the text of the title tag
- Find the 5th link of a menu and change it’s css property to
- Modify the background color of all
h1tags with a class of
- Grab all
litags within a
- Find an image with an id of
iconand shift it 30 pixels to the left
- Generate a new
divand insert it between the 4th and 5th paragraphs
- And many many more!
Nodes and Elements
The DOM looks at itself in terms of Nodes. It may seem like each HTML element is a node, and while this is true, there is more to it. There are many types of nodes in the DOM, 12 in all. We’ll focus on just the first 3 since we can accomplish just about anything we need to with them. They are 1. Element Nodes, 2. Attribute Nodes, and 3. Text Nodes. Note: The numbers 1, 2, and 3 are the actual representation of Elements, Attributes, and Text Nodes in the DOM, they are not here just to list them numerically!
Let’s take a look at a very simply example of HTML to show how and where these three node types come into play:
<ul id="domtut"> <li>Search</li> <li>Design</li> <li></li> </ul>
Viewing this another way, it may be represented by the following diagram:
This is pretty interesting. What we have here is the HTML you can see when you open the file or view the source code in a browser. The orange color items represent the actual HTML, and any text inside the HTML. The color coded boxes are more representative of the formal DOM structure. Black represents Element Nodes, Grey shows Attribute Nodes, and Blue is what depicts Text Nodes. You see, a picture is worth a thousand words!
Element Nodes Don’t Contain Text
How to Grab Element Nodes
Get an Element by ID
Often times the use case we’ll see with this method is by calling it, and assigning it’s result to a variable. That variable then acts like a handle into that specific point in the DOM. Think of it like opening a file, and this is the file handle so to speak. We can then use that variable to call methods on that element, read properties of the element, or change that element. This is not a copy of that element, we’ll be operating directly on that element within the DOM once we start calling methods on it. For example:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Document Object Model Tutorial</title> </head> <body> <ul id="domtut"> <li>Search</li> <li>Design</li> <li>Social</li> <li></li> <li></li> </ul> </body> </html> var dommer = document.getElementById('domtut'); console.log(dommer.nodeName); // UL console.log(dommer.nodeType); // 1 (Element)
Get Elements by Tag
So what if we need to get more than one element? Here we can make use of the closely related method:
Now check out that this method here is using the plural version of Elements in the method name. That is because it expects to find many elements, since a given HTML tag will hardly be unique on a page. We could have many different div tags, or p tags, or a tags. With this method, it will scan the entire document and return any elements that match the selector. Using this method on the same HTML would produce this result:
var lis = document.getElementsByTagName('li'); console.log(lis.length); // 5 console.log(lis); // HTMLCollection[li, li, li, li, li] console.log(lis.innerHTML) // Search console.log(lis.childNodes) // NodeList[<TextNode textContent="Design">] console.log(lis.nodeType) // 1
Restricting Elements to Grab
In the example above we were grabbing all li elements on the page. Let’s say we had two sets of unordered lists on the page, and we only wanted to grab the child li elements from one of them. We can do that by using a combination of methods called on various objects. We are not limited to calling these methods only on the document itself. For example:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Document Object Model Tutorial</title> </head> <body> <ul id="domtut"> <li>Search</li> <li>Design</li> <li>Social</li> <li></li> <li></li> </ul> <ul id="lang"> <li>php</li> <li>js</li> </ul> </body> </html> var langlis = document.getElementById('lang'); var restricted = langlis.getElementsByTagName('li') console.log(restricted.length); // 2 console.log(restricted); // HTMLCollection[li, li] console.log(restricted.innerHTML) // php console.log(restricted.childNodes) // NodeList[<TextNode textContent="js">]
By having a command of the DOM, and what methods are available to operate on it, we are able to get anywhere in the page we need to be.
Changing the DOM
Starting with the easiest thing we could do, let’s modify an attribute of some example HTML. We’ll be looking at two important methods for dealing with attributes.
As ever, a demo is needed!
var someElement = document.getElementById('domtut'); console.log(someElement.getAttribute('id')); someElement.setAttribute('id', 'newid'); console.log(someElement.getAttribute('id'));
This code fetches the
ul that has an id of
domtut, logs out the captured value, then makes use of the
setAttribute method to set a new id to that very element, and lastly logs out the new value that has been modified. So there you have it, 4 simple lines of code to show how to make use of the
Creating DOM Content
So let’s consider that in some of our prior example HTML, we did have some empty
Our updated HTML will now look like this with the last two list items now populated!
This is pretty cool, an li will be created into the world. Actually, it is created into the DOM, but our new li feels lost. He has no place in the world. We need to help him find where he should be. We can do this by making use of another new method.
So now that we have our newly created element, it must be appended somewhere into the DOM. This is how things would look so far:
var newlyCreated = document.createElement('li'); var someElement = document.getElementById('domtut'); someElement.appendChild(newlyCreated);
If you run this snippet in firebug, you will see a new li item get added to that first list. In fact, start clicking run like a mad man and watch those li items keep getting generated and appended into the page like crazy! Don’t worry, once you have fun doing this, you can just refresh the browser and everything will be back to normal 🙂 This is a great example though of how to dynamically create, and then append items on the fly. Cool!
Creating Text Nodes
You’ll notice that we did in fact create a new li element on the page. In fact, maybe you did our little exercise and clicked run repeatedly if you have been drinking some nice fresh Starbucks. One thing that is missing however from our new li item is any data inside of it. It has no text. We could easily add dome test by simply setting the innerHTML property like so:
newlyCreated.innerHTML = 'Caffiene and Mocha!';
This does in fact work just fine, and you’ll see the page update in real time if you actually run the code. There is a bit of a more precise way to do this however, let’s check it out.
var newText = document.createTextNode(‘Caffiene and Mocha!’);
Our new script in full would look like this:
var newlyCreated = document.createElement('li'); var someElement = document.getElementById('domtut'); someElement.appendChild(newlyCreated); var newText = document.createTextNode('Caffiene and Mocha!'); newlyCreated.appendChild(newText);
So yes, just setting the innerHTML property of the element may be a little quicker, but the second method of creating the text node and appending it in the
DOM is the more formal and precise way to accomplish this.
Alternatives to appendChild
You may be up to your eyeballs in the DOM at this point, but there is one more thing we need to cover! We can insert elements into the DOM in more ways than one. Here is an alternate way to accomplish the same thing.
var theParent = document.getElementById('domtut'); var newLi = document.createElement('li'); var insertPoint = theParent.getElementsByTagName('li'); theParent.insertBefore(newLi,insertPoint); var newText = document.createTextNode('Caffiene and Mocha!'); theParent.getElementsByTagName('li').appendChild(newText);
Whoa Nelly! What the heck is going on here? Let’s talk it through, as this helps to understand better.
- Grab the parent element
- Create a new element
- Grab the element we want to insert our new element before. The
getElementsByTagNamemethod can be called on the
theParent. The only difference is where in the DOM the handle starting point will be.
- Insert the new element. Note! Unlike the previous step, we must use
theParentto call the
insertBeforemethod, it will not work otherwise!
- Lastly, we simply create a text node, and then append it to our new
And with that friends, you have completed the Vegibit Crash Course on the Document Object Model! Congratulations 🙂