DOM Programming — An Introduction
Published: 2016-10-03
Overview
This blog post isthe JavaScript DOM Programming seriesthe first installment. Since it’s the first, it’s necessary to state the original intent and motivation. In my learning and work, I’ve found that most people are both familiar and unfamiliar with the concept of the DOM. Familiar, because DOM comes up frequently in discussions; unfamiliar, because when we try to articulate our understanding precisely, it often becomes vague, and we tend to lumpJS,DOMand evenjQueryand similar JS libraries together, without a deep understanding. Insufficient conceptual understanding naturally leads to disorder in application. In code, this shows up as poor readability and a lack of standards and consistency. I face these issues too, so I self-studied“DOM Scripting: Web Design with JavaScript and the Document Object Model (2nd Edition)”This book. One of its authors,Jeremy Keithis one of the designers behind Web standards, so the content aligns well with mainstream standard-driven design. Standards are forward-looking and authoritative, which is why I chose this book to learn the DOM. This blog series is essentially my study notes. It organizes content by distilling the book’s essence, and, on top of accuracy, adds my own understanding and extensions. I hope to grow together with you through learning and sharing.
Having stated the purpose, let me briefly summarize the content focus of this blog. Readers should understand the basics of JavaScript syntax, ideally with some coding practice. This isn’t because the content is esoteric, but to help you better grasp the underlying “Way.” What “Way”? Generally, junior coders get stuck on syntax, solving problems at the level of “technique,” rarely thinking beyond syntax to deeper issues. As a result, they miss the “Way” of coding principles, habits, and approaches. This article moves from simple to deep. If you have a bit of JS syntax background, you can follow along. The article doesn’t dwell on syntax minutiae. You may already know parts of it, but the real goal is tounderstand the thinking and principles behind DOM scripting. Progressive enhancement, graceful degradation, and user-centered design are critical to any web development. These ideas run through all code examples in this series.
Let’s begin our journey into the DOM.
JavaScript and the DOM
This section introduces the precise concept of the DOM and explains the relationship between JavaScript and the DOM.
1) W3C Standards
To discuss the DOM, we must start with an organization every web developer knows ————W3C (World Wide Web Consortium)We often mention W3C standards in development discussions. So what exactly are W3C standards?
Structured standard languages (HTML, XML, etc.);
Presentation standard languages (CSS Cascading Style Sheets);
Behavior standard languages (DOM and ECMAScript);
In other words, W3C is a standards body, and the DOM is one of the standards it defines. Browsers we use play the role of standard implementers. Modern mainstream browsers have implemented HTML, CSS, and DOM to varying degrees. This categorization reflects W3C’s advocacy for separating content, presentation, and behavior in web documents, with the DOM responsible for adding interactivity to documents.
Why define standards? The web evolved chaotically, accompanied by nearly a decade of browser wars. After prolonged push and pull, to maximize benefits, the surviving browser vendors compromised on standards. This transformed web development from disorder into a profession requiring rigorous training. For developers, a wealth of standards is beneficial: once standards are unified, web developers no longer write large amounts of browser sniffing and inefficient branching for different browsers, avoiding duplicate script sets for the same feature.
2) What is the DOM?
Simply put, the DOM is a way to abstract and conceptualize a document’s content.
Document Object Model(Document Object Model, abbreviated asDOM). Like a “world object model” in the real world, we have common ground on abstract concepts, enabling us to express complex meanings with simple words. For example, if you say “the third tree from the left,” you and your listener must share an understanding of “left” and “third” to communicate smoothly. The Document Object Model targets a document. If browsers all used different ways to manipulate webpages, the same code would break across browsers.
W3C defines the DOM more broadly as:
an interface independent of system platform and programming languageinterfaceThrough this interface, programs and scripts can dynamically access and modify a document’s content, structure, and style.
In other words, a standardized DOM letsany programming languageoperate on documents written inany markup languagewrittenany documentWe see that W3C defines the DOM as a set of interfaces, so the DOM is anAPI(Application Programming Interface). Put simply, an API is a set of fundamental conventions recognized by relevant parties. There are many real-world analogues: Morse code, time zones, the periodic table — standards across disciplines to facilitate communication and collaboration.
In software, despite many languages, many tasks are the same or similar. That’s why we need APIs — for smoother integration. Once you master a standard, you can apply it in many contexts. Syntax may vary by language, but the conventions remain. Thus, per the DOM standard, we can use JavaScript to manipulate HTML documents, or use languages like PHP or Python to parse XML documents, and so on.
At this point, we can summarize therelationship between the DOM and JavaScript. In web technology, the DOM truly binds HTML/XHTML and CSS together — that is, we use the W3C DOM to process documents and stylesheets. “DOM scripting” covers using any language that supports the DOM API to process any marked-up document. For web documents specifically, JavaScript’s ubiquity makes it the best choice for DOM scripting. That’s why “JavaScript” is in the title of this series.
Start with the basic APIs
The previous summary focused on the DOM’s abstract concepts. If you’re new to the DOM, your understanding may still be superficial. So this section uses a few basic DOM methods to reinforce your grasp and prepare for the practical case in the next section.
1) The “O” in DOM
We know DOM (Document Object Model) stands for Document Object Model. We need to look more closely at Object here. First, the concept of objects in JS:
Object: a data entity composed of a set of properties and methods.
JavaScript objects fall into three types: 1) User-defined objects: created by the programmer 2) Native objects: built into JavaScript, such as Array, Math, and Date 3) Host objects: provided by the browser, such as window and document
The third type, host objects, is our focus. JavaScript is interpreted and must run in a host environment. On the client side, that’s the browser. The window object corresponds to the browser window, and its properties and methods are generally called the BOM (Browser Object Model). We don’t need to deal much with the BOM; we focus on the page content inside the window. The document object mainly handles page content. So in what follows, we’ll discuss almost exclusively the document object’s properties and methods.
Now we get to a key point for concretely understanding the DOM:The DOM represents a document as a treeThis tree can be thought of as a family tree. We use parent, child, and sibling to denote relationships. The basic unit in a family tree is a family member; the basic unit in the DOM tree is a node. So, when we see a web document, think of it as a node tree. So what is a node?
2) Nodes
There are many node types in the DOM. Let’s look at three: element nodes, text nodes, and attribute nodes. For convenience, here’s a simple web documentListing A:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Shopping list</title>
</head>
<body>
<h1>What to buy</h1>
<p title="a gentle reminder">Don't forget to buy this stuff.</p>
<ul id="purchases">
<li>A tin of beans</li>
<li class="sale">Cheese</li>
<li class="sale important">Milk</li>
</ul>
<script></script>
</body>
</html>Element nodesare essentially the tags themselves; a tag’s name is the element’s name. For example, the root element of the entire node tree is an element.
Text nodesare the text inside element nodes; they are also a node type. For example, the text inside the
element, “Don’t forget to buy this stuff.”, is a text node.
Attribute nodesprovide more specific descriptions of an element and always reside within an element node. For example, the
element’s title attribute is an attribute node.
3) Getting elements
With node concepts introduced, let’s learn the DOM API, starting with three methods for getting elements.
1) getElementById
document.getElementById('id');
This method returns the object corresponding to the element node with the given id attribute value. In other words, the call returns an object corresponding to a unique element within document, since id should be globally unique. Using the example above,document.getElementById('purchases')retrieves the element with id purchases, the<ul>node object;
2) getElementsByTagName
document.getElementsByTagName('tag');
This method takes a tag name and returns an array-like object whose items each correspond to an element with that tag in the document. That is, the returned collection contains element node objects. In Listing A’s<script>tag, add the following code:
var items = document.getElementsByTagName('li');
for(var i = 0; i < items.length; i++){
console.log(typeof items[i]);
}In the console we’ll see three “object”s.
getElementsByTagName allows a wildcard as its argument to get the total number of element nodes under a given object. Note the wildcard must be in quotes; otherwise, the JS interpreter will treat thesymbol as the multiplication operator. For example, to find how many elements a document has, you can use `document.getElementsByTagName('').length`;
3) getElementsByClassName
document.getElementsByClassName('class');
This method is similar to getElementsByTagName in that it returns a collection, but the argument is an HTML class name. The returned items are element nodes whose class matches the argument. You can pass multiple class names separated by spaces, meaning elements thatsimultaneouslycontain multiple class names will be selected. Using Listing A again,document.getElementsByClassName('important sale');returns a collection that includes the element on line 13. When there are multiple class names, their order does not affect the result. That is, executingdocument.getElementsByClassName('sale important');yields the same result. If an element’s class attribute includes, but is not limited to, the specified class names, it will also be selected. If we add another element to Listing A,<li class="sale important xxx">example</li>it will also be selected.
This method is very useful in practice, but only newer browsers support it. To use it reliably, let’s implement a similar function ourselves, also named getElementsByClassName:
/**
* Get element nodes by class name; this version only supports a single class name
* @param {Object} node The search root in the DOM tree; an element node
* @param {String} classname The class name to search for (single class)
* @return {Array} An array of element nodes that contain the specified class name
*/
function getElementsByClassName(node, classname) {
// Check whether the passed node has getElementsByClassName
if (node.getElementsByClassName) {
// Browser supports it; use the native method
return node.getElementsByClassName(classname);
} else {
var results = new Array();
var elems = node.getElementsByTagName("*");
// Traverse all tags under node; find elements with the class and add to results
for(var i = 0; i < elems.length; i++){
if (eles[i].className.indexOf(classname) != -1) {
results[results.length] = elems[i];
};
}
return results;
}
}We’ll encounter similar compatibility issues later and will explore solutions in detail.
Based on the above, here’s a brief summary to deepen understanding. For the DOM, a document is a node tree, and every element node in the document is an object. Moreover, each of these objects comes with a set of very useful methods thanks to the DOM. Using these predefined methods, we can retrieve information about any object in the document and even change element attributes. Next, let’s learn some DOM methods for getting and setting attributes.
4) Getting and setting attributes
Once we have a specific element, we can retrieve its attributes and dynamically change attribute values.
1) getAttribute
object.getAttribute('attribute');
Unlike the methods introduced earlier, getAttribute does not belong to the document object, so you can’t call it on document. It must be called on an element node to get that node’s attribute value. If the element does not have the attribute, it returns null.
Since only one p tag in Listing A has a title attribute, the console will printa gentle reminderas the text.
2) setAttribute
object.setAttribute('attribute', value);
Like getAttribute, setAttribute only applies to element nodes. If the attribute already exists, its value will be overwritten.
var shopping = document.getElementById('purchases');
shopping.setAttribute("title", "a list of goods");Because the element with id purchases does not have a title attribute, setAttribute performs two steps: it creates the title attribute and then sets its value to “a list of goods.”
Here’s an important detail: after modifying the document via setAttribute, if you view source in the browser, you will still see the original attribute value. In other words, changes made by setAttribute are not reflected in the document’s source. This discrepancy arises from how the DOM works:load the static content first, then refresh dynamically; dynamic refreshes don’t affect the static source. This is the DOM’s power: update page content without reloading the page.
Summary
Let’s wrap up the first installment of thethe JavaScript DOM Programming seriesseries. We introduced the basics of the DOM, the relationship between the DOM and JavaScript, and some core DOM APIs:
getElementById;
getElementsByTagName;
getElementsByClassName;
getAttribute;
setAttribute;
This post is theory-heavy. The DOM offers many other properties and methods. In the next article, we’ll demonstrate the DOM’s power with an image gallery example.
Last updated