Web Programming Step by Step

Chapter 8
The Document Object Model (DOM)

Except where otherwise noted, the contents of this presentation are Copyright 2009 Marty Stepp and Jessica Miller.

Valid XHTML 1.1 Valid CSS!

8.1: Global DOM Objects

The six global DOM objects

Every Javascript program can refer to the following global objects:

namedescription
document current HTML page and its content
history list of pages the user has visited
location URL of the current HTML page
navigator info about the web browser you are using
screen info about the screen area occupied by the browser
window the browser window

The window object

the entire browser window; the top-level object in DOM hierarchy

The document object

the current web page and the elements inside it

The location object

the URL of the current web page

The navigator object

information about the web browser application

The screen object

information about the client's display screen

The history object

the list of sites the browser has visited in this window

Unobtrusive JavaScript (8.1.1)

Obtrusive event handlers (bad)

<button id="ok" onclick="okayClick();">OK</button>
// called when OK button is clicked
function okayClick() {
	alert("booyah");
}

Attaching an event handler in JavaScript code

// where element is a DOM element object
element.event = function;
var okButton = document.getElementById("ok");
okButton.onclick = okayClick;

A failed attempt at being unobtrusive

	<head>
		<script src="myfile.js" type="text/javascript"></script>
	</head>
	<body>
		<div><button id="ok">OK</button></div>
// global code
var okButton = document.getElementById("ok");
okButton.onclick = okayClick;   // error: okButton is undefined

The window.onload event (8.1.1)

window.onload = functionName;   // global code

// this will run once the page has finished loading
function functionName() {
	element.event = functionName;
	element.event = functionName;
	...
}

An unobtrusive event handler

<!-- look Ma, no JavaScript! -->
<button id="ok">OK</button>
window.onload = pageLoad;  // global code

// called when page loads; sets up event handlers
function pageLoad() {
	var okButton = document.getElementById("ok");
	okButton.onclick = okayClick;
}

function okayClick() {
	alert("booyah");
}

Common unobtrusive JS errors

Anonymous functions (8.1.2)

function(parameters) {
	statements;
}

Anonymous function example

window.onload = function() {
	var okButton = document.getElementById("ok");
	okButton.onclick = okayClick;
};

function okayClick() {
	alert("booyah");
}

or the following is also legal (though harder to read and bad style):

window.onload = function() {
	var okButton = document.getElementById("ok");
	okButton.onclick = function() {
		alert("booyah");
	};
};

The keyword this (8.1.3)

window.onload = pageLoad;

function pageLoad() {
	var okButton = document.getElementById("ok");
	okButton.onclick = okayClick;  // bound to okButton here
}

function okayClick() {           // okayClick knows what DOM object
	this.innerHTML = "booyah";     // it was called on
}

Fixing redundant code with this

<fieldset>
	<label><input id="Huey"  type="radio" name="ducks" /> Huey</label>
	<label><input id="Dewey" type="radio" name="ducks" /> Dewey</label>
	<label><input id="Louie" type="radio" name="ducks" /> Louie</label>
</fieldset>
function processDucks() {
	if (document.getElementById("huey").checked) {
		alert("Huey is checked!");
	} else if (document.getElementById("dewey").checked) {
		alert("Dewey is checked!");
	} else {
		alert("Louie is checked!");
	}
	alert(this.id + " is checked!");
}

8.2: DOM Element Objects

Modifying text inside an element

var paragraph = document.getElementById("welcome");
paragraph.innerHTML = "Welcome to our site!";  // change text on page

DOM element objects have the following properties:

Abuse of innerHTML

// bad style!
var paragraph = document.getElementById("welcome");
paragraph.innerHTML = "<p>text and <a href="page.html">link</a>";

Adjusting styles with the DOM (8.2.2)

<button id="clickme">Color Me</button>
window.onload = function() {
	document.getElementById("clickme").onclick = changeColor;
};
function changeColor() {
	var clickMe = document.getElementById("clickme");
	clickMe.style.color = "red";
}

Common DOM styling errors

Unobtrusive styling (8.2.3)

function okayClick() {
	this.style.color = "red";
	this.className = "highlighted";
}
.highlighted { color: red; }

8.3: The DOM Tree

Complex DOM manipulation problems

How would we do each of the following in JavaScript code? Each involves modifying each one of a group of elements ...

The tree of DOM objects

DOM tree

Types of DOM nodes (8.3.1)

<p>
	This is a paragraph of text with a 
	<a href="/path/to/another/page.html">link</a>.
</p>
DOM Tree

Traversing the DOM tree (8.3.2 - 8.3.3)

every node's DOM object has the following properties:

name(s) description
firstChild, lastChild start/end of this node's list of children
childNodes array of all this node's children
nextSibling, previousSibling neighboring nodes with the same parent
parentNode the element that contains this node

DOM tree traversal example

<p id="foo">This is a paragraph of text with a 
	<a href="/path/to/another/page.html">link</a>.</p>
navigate tree

Element vs. text nodes

<div>
	<p>
		This is a paragraph of text with a 
		<a href="page.html">link</a>.
	</p>
</div>

Selecting groups of DOM objects (8.3.5)

name description
getElementsByTagName returns array of descendents that have the given HTML tag, such as "div"
getElementsByName returns array of descendents that have the given name attribute (mostly useful for accessing form controls)

Getting all elements of a certain type

highlight all paragraphs in the document:

var allParas = document.getElementsByTagName("p");
for (var i = 0; i < allParas.length; i++) {
	allParas[i].style.backgroundColor = "yellow";
}
<body>
	<p>This is the first paragraph</p>
	<p>This is the second paragraph</p>
	<p>You get the idea...</p>
</body>

Combining with getElementById

highlight all paragraphs inside of the section with ID "address":

var addr = document.getElementById("address");
var addrParas = addr.getElementsByTagName("p");
for (var i = 0; i < addrParas.length; i++) {
	addrParas[i].style.backgroundColor = "yellow";
}
<p>This won't be returned!</p>
<div id="address">
	<p>1234 Street</p>
	<p>Atlanta, GA</p>
</div>

Creating new nodes (8.3.5)

// create a new <h2> node
var newHeading = document.createElement("h2");
newHeading.innerHTML = "This is a heading";
newHeading.style.color = "green";

Modifying the DOM tree

Every DOM element object has these methods:

name description
appendChild(node) places given node at end of this node's child list
insertBefore(newold) places the given new node in this node's child list just before old child
removeChild(node) removes given node from this node's child list
replaceChild(newold) replaces given child with new node

Adding a node to the page

window.onload = function() {
	var thisSlide = document.getElementById("slide38");
	thisSlide.onclick = slideClick;
}

function slideClick() {
	var p = document.createElement("p");
	p.innerHTML = "A paragraph!";
	this.appendChild(p);
}

Firebug's debugger

Firebug JS Debugger

Breakpoints

Firebug breakpoint

Stepping through code

Firebug breakpoint

Debugging CSS property code

Firebug Debug CSS

General good coding practices