DOM Objects
This lesson is part of the Web Programming 1 Course.
We've been spending a lot of time learning about objects in JavaScript. Here's what we know about them up to this point:
- We can use objects to simulate objects in the real world (and to simulate virtual objects, such as dates and emails). We can create objects to 'model' the data we are working with. We created objects to represent a dog that we may track in a program, and a receipt that represents a business transaction. If you've been doing the worksheets, you created book objects that might be used in a library tracking system. You also created an object that simulates a bank account, and keeps track of simple transactions.
- Objects are more than just properties. We can make them DO things by adding methods to them.
- Objects can become very complex. That is, an object can be made up of many other objects. For example, we created a 'car' object that had a 'engine' property. The engine, nested within the car, was itself an object with it's own set of properties. This is how complex systems are put together in the real world! Various objects are used as parts in assembling other objects. Just think of all the objects and components that go into making an airplane!
If you plan to try out the code samples in this lesson, make sure to set up your web page by putting the script element after the body element, like so:
<html>
<head>
<title>DOM Object Sample Code</title>
</head>
<body>
<!--We'll add some HTML elements here-->
</body>
<script>
// We'll add JavaScript code here
</script>
</html>
I mentioned in a previous lesson that the script element is usually placed inside the head element, but for this lesson we need it to b after the body. I will explain why at the end of the lesson.
Now that you know the basics of objects in JavaScript, I can tell you that when the browser loads web page it creates a highly complex object that represents the HTML document and all of the HTML elements within it.
The Document Object Model
When a web page is loaded into the browser, there is a tremendous amount of work being done under the hood. The browser converts each and every HTML element into an object, and all of these objects together are used to make a model that simulates the entire web page. This model is stored in the memory (RAM) of the computer and it is known as the Document Object Model. We can use use JavaScript code to manipulate any object in the DOM, and the changes will automatically be reflected in the browser window.
The objects that make up the DOM are technically called nodes but I like to call them element objects, because as you'll see in this lesson, every HTML element in your HTML document will be converted into an object that has various properties. You can use JavaScript code to access and update these properties, which can affect the way they appear in the browser. Each one of these element objects is complex, but luckily, they all share a common set of properties. So if you become familiar with some of these common properties, then you'll know how to work with any element object. Here is a reference that shows you all of the common properties and methods of element objects. It's a bit overwhelming, but each property and method serves a purpose and together they allow you to do all sorts of powerful things with a web page. At this point in the course, we can finally see how JavaScript and HTML code work together in a web page.
The DOM is a hierarchical data structure. This makes sense because as you already know, an HTML document is hierarchical (elements are nested within other elements). And when the browser loads a page and constructs the DOM, it follows the hierarchical structure as the HTML elements. The root of the DOM is an object that gets stored in a variable named document (because it represents the HTML document that the browser has loaded). You do not declare this variable when you write code, it is created for you.
Go ahead and console log the built-in document variable, like so:
console.log(document);
If you look at the console log in the Web Developer tools, you'll see that it is a highly complex object, loaded with many properties and methods.
If you use the dir() method of the console object, instead of the log() method, you'll get a different view of the document object, which will allow you to inspect its properties, and drill down into the objects that are nested within it.
The getElementById() Method
There are many useful properties and methods nested within the document object, but there is one in particular that we'll be using heavily. We can use the getElementById() method of the document object to 'get' any HTML element object from the DOM, as long as the HTML element has an id attribute.
Assume that you have an H1 element in your web page, like this one:
<h1 id="main-heading">The DOM (Document Object Model)</h1>
Notice that the id attribute of the H1 element is set to a value of 'main-heading'. This value can be passed in as a parameter when invoking the document.getElementById() method like so:
const h1 = document.getElementById("main-heading");
console.log(h1); // gives you the element view of the object
console.dir(h1); // allows you to drill down into the properties of the object
In this code sample, the h1 variable is storing an object that represents the H1 element (which is why I like to call them 'element objects' rather than 'nodes'). The document.getElementById() method returns the element whose id attribute matches the parameter that was passed in (note that we passed in a string, which is enclosed in quotation marks). Once you have the element object assigned to a variable, you can use the dot operator to access its properties and invoke it's methods.
Let's begin to experiment with this element object by accessing (looking at) it's innerHTML property (pay close attention to the capitalization):
console.log(h1.innerHTML);
The innerHTML property will show you any HTML elements and content that is nested within the element. In this example, there is only content nested within the H1 element.
Now let's update the innerHTML property and see how JavaScript can be used to manipulate the HTML in a web page:
h1.innerHTML = "I <b>LOVE</b> JavaScript!";
When you refresh the page and this line of code executes, you'll see that you have altered the contents of the H1 element.
Suppose you have this list in your HTML code:
<ul id="topics-list">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
You can use JavaScript to add an LI element to the list like so:
// first 'get a handle' on the list:
const ul = document.getElementById("topics-list");
//then concatenate an LI element to the innerHTML
ul.innerHTML += "<li>Python</li>";
Attributes In HTML Code Become Properties of Element Objects
When you get a handle on an element, its attributes become properties of the element object (although this is not always true). Consider this HTML code:
<img id="imgDog" src="../images/happy-dog.jpg" alt="Picture of a happy dog" />
Notice the three attributes that have been added to the img element. Now let's 'get a handle on it' so that we can inspect the properties of the element object:
const dogImg = document.getElementById("imgDog");
console.log(dogImg.id);
console.log(dogImg.src);
console.log(dogImg.alt);
The words 'attribute' and 'property' are synonyms. And hopefully you can see how they they are closely related in HTML and JavaScript. For some reason, I'm not sure why, they are referred to as 'attributes' in HTML, and 'properties' when dealing with objects in JavaScript. Either way, they are both used to provide details about something. If you really dig deep into JavaScript, you will find a subtle difference between an attribute and a property when it comes to element objects, but we won't get into those gory details in this course.
You could also use the getAttribute() method to access attributes of an element object. The method takes a (string) parameter that represents the name of the attribute that you wish to get:
const pathToImg = dogImg.getAttribute("src");
console.log(pathToImg);
You can alter the HTML element's attributes in one of two ways in your JavaScript code:
dogImg.src = "../images/angry-dog.jpg";
// or
dogImg.setAttribute("src", "../images/angry-dog.jpg");
This example demonstrates that you can update the src attribute of the img element by either changing the src property of the element object, or by invoking the setAttribute() method. Note that when you call setAttribute() you must pass in two parameters. The first is the name of the attribute you wish to update (a string), and the second is the value you wish to set it to. It's pretty common in many programming languages to offer more than one way to accomplish a task. This can be confusing for beginners, but it gets easier as you gain experience.
The Style Property of an Element Object
Every element object has a style property, which is an object that contains properties for controlling the CSS properties applied to an object. The following example demonstrates how we can manipulate style properties of the h1 variable that we declared previously:
h1.style.backgroundColor = "blue";
h1.style.color = "white";
h1.style.fontSize = "30px"
This example also demonstrates that every element in a web page is a complex object, and the style property (which every element object has) is an object made up of its own properties. Note the use of quotes when assigning values to the properties of the style object, you should use strings when updating the style of an object in your JavaScript code.
It's important to note that in CSS code the property names often have dashes in them, and if you wanted to control the main header from your CSS code, you could do it like this:
#main-heading{
background-color: blue;
color: white;
font-size: 30px;
}
The dashes used in CSS property names are problematic in JavaScript. To work around this, you must omit the dash and use camelCase. So, the background-color property in CSS becomes the backgroundColor property of the style object in JavaScript.
Getting User Input
A very common task for a web developer is to use JavaScript to extract data entered into a form on a web page. Consider this very simple (and incomplete) form:
<form>
<label>Enter Your Full Name:</label>
<input type="text" id="txtFullName" value="Pedro Martinez" />
</form>
I have pre-filled the form by setting the value attribute of the text input element.
You can use JavaScript to get user input from this form like so:
const txt = document.getElementById("txtFullName");
const input = txt.value;
console.log(input);
After getting a handle on a text input, you can extract the data entered into it by accessing the value property of the element object.
The Window Object
We began this lesson by talking about the document object that the browser creates and populates when it loads a web page. There is also another object that the browser creates, which is aptly named window because it represents the browser window. You can console log the window object like so:
console.log(window);
You'll see that it contains some properties related to the browser window, such as the location property which is the URL that appears in the URL bar of the browser window. You'll also see that it includes a property named document, which is the exact same object that we have been discussing in this lesson. Conceptually, this should make sense because an HTML document gets loaded inside of the browser window. We'll be using the window object in a future lesson.
Why did we put the script element after the body element?
At the beginning of this lesson I instructed you to set up your web page so that the script element came after the body element. The reason for this is that when the browser loads a web page, it executes the code from top to bottom. Our JavaScript code referred to various HTML elements that are inside the body (by 'getting a handle on them'). If you try to 'get a handle' on an element before the browser has loaded it, then you will not get the correct result. So by moving the script element after the body, we know that all the elements will have been loaded by the time our JavaScript code executes. We'll be talking more about this in a future lesson.
Summary
This is a big moment in your web programming career! You are beginning to use JavaScript code to interact with the HTML elements in a web page. There are so many more properties and methods of element objects that we did not discuss in this lesson. Part of your mission as a web developer is to become familiar with many of them!