What You’ll Learn in This Lesson:
How the W3C DOM standard makes dynamic pages easier to control
The basics of the standard DOM objects: window
, document
, history
, and location
How to work with DOM nodes, parents, children, and siblings
How to access and use the properties of DOM nodes
How to access and use DOM node methods
How to control element positioning with JavaScript
How to hide and show elements with JavaScript
How to use JavaScript to add and modify text within a page
The preceding lesson introduced you to the basic concepts of programming in JavaScript; this lesson will help you better understand the Document Object Model (DOM), which is the structured framework of a document within a web browser. When using JavaScript objects, methods, and other functionality (in addition to basic HTML), controlling the DOM enables you to develop rich user experiences.
One advantage of JavaScript over plain HTML is that client-side JavaScript scripts can manipulate the web browser and documents (including their contents) right in the browser after the content has been loaded. Your script can load a new page into the browser, work with parts of the browser window and the loaded document, open new windows, and even modify text within the page—all dynamically, without requiring additional requests to a server.
To work with the browser and documents, JavaScript uses the hierarchy of parent and child objects found within the DOM. These objects, which are organized into a treelike structure, represent all the content and components of a web document and the browser that renders it.
Note
The DOM is not part of JavaScript or any other programming language. Rather, it’s an application programming interface (API) built into the browser.
The objects in the DOM have properties that describe the web browser or document, and methods, or built-in code that enables you to work with parts of the web browser or document. You’ll learn more about these properties and methods and you will practice referencing or using them throughout this lesson.
You’ve seen DOM object notation already in these lessons, even if it wasn’t called out as such. When you refer to a DOM object, you use the parent object name followed by the child object name or names, separated by periods. For example, if you need to refer to a specific image loaded in your web browser, these are child objects of the document
object. But that document
object, in turn, is a child of the DOM’s window
object. So, to reference an image called logo_image
, the DOM object notation would look like this:
window.document.logo_image
At the top of the browser object hierarchy is the window
object, which represents a browser window. You’ve already used at least one method of the window
object, alert
, which displays a message in an alert box.
A user might have several windows open at a time, each with its own distinct window
object, since different documents will presumably be loaded in each window. Even if the same document is loaded into two or more windows, they are considered distinct window
objects because they are in fact distinct instances of the browser. However, when referencing window.document
(or just document
) in your JavaScript, the reference is interpreted to be the window currently in focus—the one actively being used. You’ll learn more about windows, including how to reference out-of-focus windows, in Lesson 24, “Responding to Events and Using Windows.”
The window
object is the parent object for all the objects we will be looking at in this lesson. Figure 21.1 shows the window
section of the DOM object hierarchy and a variety of its objects.
Just as it sounds like it would, the document
object represents a web document. Web documents are displayed within browser windows, so it shouldn’t surprise you to learn that the document
object is a child of the window
object. Because the window
object always represents the current window, as you learned in the preceding section, you can use window.document
to refer to the current document. You can also simply refer to document
, which automatically refers to the current window.
Note
In previous lessons, you’ve already used the document.write
method to display text within a web document. The examples in earlier lessons used only a single window and document, so it was unnecessary to use window.document.write
, but this longer syntax would have worked equally well.
In the following sections, you will look at some of the properties and methods of the document
object that will be useful in your scripting.
Several properties of the document
object include information about the current document in general:
document.URL—Specifies the document’s URL. You (or your code) cannot change the value of this property.
document.title—Refers to the title of the current page, defined by the HTML <title>
tag. You can change the value of this property.
document.referrer—Returns the URL of the page the user was viewing before the current page—usually the page with a link to the current page. As with document.URL
, you cannot change the value of document.referrer
. Note that document.referrer
will be blank if a user has directly accessed a given URL directly.
document.lastModified—Indicates the date the document was last modified. This date is sent from the server along with the page.
document.cookie—Enables you to read or set a cookie used within the document.
document.images—Returns a collection of images used in the document.
As an example of a document property, Listing 21.1 shows a short HTML document that displays its last modified date using JavaScript.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Displaying the Last Modified Date</title>
<meta name="viewport"
content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Displaying the Last Modified Date</h1>
<p>This page was last modified on:
<script>
document.write(document.lastModified);
</script>
</p>
</body>
</html>
Figure 21.2 shows the output of Listing 21.1.
If you use JavaScript to display the value of this document
property, you don’t have to remember to update the date each time you modify the page, should you choose to expose this information to the user. (You could also use the script to always print the current date instead of the last modified date, but that would be cheating.)
Note
You might find that the document.lastModified
property doesn’t work on your web pages or that it returns the wrong value. The date is received from the web server, and some servers do not maintain modification dates correctly.
The simplest document
object methods are also the ones you use most often. In fact, you’ve used one of them already in the lessons so far, in very basic examples. The document.write
method prints text as part of the HTML in a document window. An alternative statement, document.writeln
, also prints text, but it also includes a newline (
) character at the end. This is handy when you want your text to be the last thing on the line in your source code.
Caution
Bear in mind that the browser displays the newline character as a space but doesn’t display it on the visible page, except inside a <pre>
container. You need to use the <br>
tag if you want an actual line break to be shown in the browser.
You can use these methods only within the body of the web page; you can’t use these methods to add to a page that has already loaded unless you reload it. You can write new content for a document, however, as the next section explains.
Note
You can also directly modify the text of a web page by using more advanced features of the DOM, as you’ll learn later in this lesson.
The document.write
method can be used within a <script>
tag in the body of an HTML document. You can also use it in a function, provided that you include a call to the function within the body of the document, as shown in Listing 21.1.
Another child of the document
object is the link
object. There can be, and very likely are, multiple link
objects in a document. Each link
object includes information about a link to another location or to an anchor.
You can access link
objects through the links
array. Each member of the array is one of the link
objects in the current page. A property of the links
array, document.links.length
, indicates the number of links in the page. You might use the document.links.length
property in a script to first determine how many links there are, before performing additional tasks such as dynamically changing the display on a certain number of links.
Each link
object (or member of the links
array) has a list of properties defining the URL that is ultimately stored in the object. The href
property contains the entire URL, and other properties define other, smaller, portions of it. The link object uses the same property names as the location
object, defined later in this lesson, so after you commit one set to memory, you will also know the other set.
You can refer to a property by indicating the link number, or position within the array, and property name. For example, the following statement assigns the entire URL of the first link stored in the array to the variable link1
:
var link1 = links[0].href;
The anchor
objects are also children of the document
object. Each anchor
object represents an anchor in the current document—a particular location that can be jumped to directly.
As with links, you can access anchors by using an array. For example, with an array called anchors
, each element of the array is an anchor
object. The document.anchors.length
property gives you the number of elements in the anchors
array. An example of using the anchors
array to your advantage would be to use JavaScript to loop through all the anchors on a given page to dynamically generate a table of contents at the top of the page.
The history
object is another child (property) of the window
object. This object holds information about the locations (URLs) that have been visited before and after the current one, and it includes methods to go to previous or next locations.
The history
object has one property you can access:
history.length—Keeps track of the length of the history list—in other words, the number of different locations the user has visited.
The history
object has three methods you can use to move through the history list:
history.go—Opens a URL from the history list. To use this method, specify a positive or negative number in parentheses. For example, history.go(
−
2)
is equivalent to clicking the Back button twice.
history.back—Loads the preceding URL in the history list. This is equivalent to clicking the Back button or using history.go(
−
1)
.
history.forward—Loads the next URL in the history list, if available. This is equivalent to clicking the Forward button or using history.go(1)
.
You can use the back
and forward
methods of the history
object to add your own Back and Forward buttons to a web document. The browser already has Back and Forward buttons, of course, but sometimes it is useful to include your own links that serve the same purpose.
Suppose you want to create a script that displays Back and Forward buttons and then use these methods to navigate the browser. Here’s the code to create the Back button:
<button type="button"onclick="history.back();">Go Back</button>
In the preceding snippet, the <button>
element defines a button labeled Go Back. The onclick
event handler uses the history.back
method to go to the preceding page in the browser’s history. The code for a Go Forward button is similar:
<button type="button"onclick="history.forward();">Go Forward</button>
Let’s take a look at these buttons in the context of a complete web page. Listing 21.2 shows a complete HTML document, and Figure 21.3 shows a browser’s display of this document. After you load this document into a browser, visit other URLs and make sure the Go Back and Go Forward buttons work as expected.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Using Custom Go Back and Go Forward Buttons</title>
<meta name="viewport"
content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Using Custom Go Back and Go Forward Buttons</h1>
<p>Buttons on this page allow you to go back or forward in
your history list.</p>
<p>These buttons should be the equivalent of the back
and forward arrow buttons in your browser's toolbar.</p>
<div>
<button type="button"
onclick="history.back();">Go Back</button>
<button type="button"
onclick="history.forward();">Go Forward</button>
</div>
</body>
</html>
Another child of the window
object is the location
object. This object stores information about the URL currently loaded in the browser window. For example, the following JavaScript statement loads a URL into the current window by assigning a value to the href
property of this object:
window.location.href="http://www.google.com";
The href
property contains the entire URL of the window’s current location. Using JavaScript, you can access portions of the URL through various properties of the location
object. To understand these properties a bit better, consider the following URL:
https://www.google.com:443/search?q=javascript
The following properties represent parts of this URL:
location.protocol—The protocol part of the URL (http
in this example)
location.hostname—The hostname of the URL (www.google.com
in this example)
location.port—The port number of the URL (443
in this example)
location.pathname—The filename part of the URL (search
in this example)
location.search—The query portion of the URL, if any (q=javascript
in this example)
The following properties can also be used, though they aren’t in this example:
location.host—The hostname of the URL plus the port number (for example, www.google.com:443
)
location.hash—The anchor name used in the URL, if any (for example, www.google.com/#home
)
The link
object, introduced earlier in this lesson, also uses this list of properties for accessing portions of the URL found in the link
object.
Caution
Although the location.href
property usually contains the same URL as the document.URL
property described earlier in this lesson. But you can’t change the document.URL
property. Always use location.href
to load a new page in a given window.
The location
object has three methods:
location.assign—Loads a new document when used as follows:
location.assign("https://www.google.com")
location.reload—Reloads the current document. This is the same as using the Reload button on the browser’s toolbar. If you optionally include the true
parameter when calling this method, the script ignores the browser’s cache and forces a reload, whether the document has changed or not.
location.replace—Replaces the current location with a new one. This is similar to setting the location
object’s properties yourself. The difference is that the replace
method does not affect the browser’s history. In other words, the Back button can’t be used to go to the preceding location. This is useful for splash screens or temporary pages that it would be useless to return to. Remember that most people expect to be able to use the back button, so you should use the location.replace
method sparingly.
Previously in this lesson, you learned how some of the most important DOM objects are organized: The window
object is a parent to the document
object, and so on. Although these objects were the only ones available in the original conception of the DOM years ago, the modern DOM adds objects under the document
object for every element of a page.
To better understand the concept of a document
object for every element, look at the simple HTML document in Listing 21.3. This document has the usual <head>
and <body>
sections, plus a heading and a single paragraph of text.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A Simple HTML Document</title>
<meta name="viewport"
content="width=device-width, initial-scale=1">
</head>
<body>
<h1>This is a Level-1 Heading.</h1>
<p>This is a simple paragraph.</p>
</body>
</html>
Like all other HTML documents, this one is composed of various containers and their contents. The <html>
tags form a container that includes the entire document, the <body>
tags contain the body of the page, and so on.
In the DOM, each container within the page and its contents are represented by an object. The objects are organized into a treelike structure, with the document
object itself at the root of the tree and with individual elements such as the heading and paragraph of text at the leaves of the tree. Figure 21.4 shows a diagram of these relationships.
The following sections examine the structure of the DOM more closely.
Note
Don’t worry if this tree structure confuses you right now; just understand that you can assign IDs to elements and refer to them in your JavaScript. Later on, you will see more complicated examples that use this newfound information about how objects are organized in the DOM.
Each container or element in a document is called a node in the DOM. In the example in Figure 21.4, each of the objects in boxes is a node, and the lines represent the relationships between the nodes.
You will often need to refer to individual nodes in scripts. You can do this by assigning an ID or by navigating the tree using the relationships between the nodes. You will get plenty of practice with nodes as you move forward in these lessons.
As you have already learned, an object can have a parent—an object that contains it—and can also have children—objects that it contains. The DOM uses the same terminology as JavaScript in this regard.
In Figure 21.4, the document
object is the parent object for the other objects shown, and it does not have a parent itself explicitly listed, although, as you’ve learned previously, the document
object is a child of the window
object. The html
object is the parent of the head
and body
objects, and the h1
and p
objects are children of the body
object.
Text nodes work a bit differently. The actual text in the paragraph is a node in itself and is a child of the p
object rather than being a grandchild of the body
object. Similarly, the text within the <h1>
tags is a child of the h1
object. Don’t worry: We’ll return to this concept throughout these lessons.
The DOM uses another term for organization of objects: siblings. As you might expect, this refers to objects that have the same parent—in other words, objects at the same level in the DOM object tree.
In Figure 21.4, the h1
and p
objects are siblings because both are children of the body
object. Similarly, the head
and body
objects are siblings under the html
object. There’s not a lot of practical use in knowing which objects are siblings, but it is offered here as some knowledge that completes the family tree.
As you’ve seen, the DOM organizes objects within a web page into a treelike structure. Each node (object) in this tree can be accessed in JavaScript. In the next sections you will learn how you can use the properties and methods of nodes to manage them.
Note
The following sections describe only the most important properties and methods of nodes and those that are supported by current browsers. For a complete list of available properties, see the W3C’s DOM specification at www.w3.org/TR/DOM-Level-3-Core/.
Previously, you used the style
property of nodes to change their style sheet values. Each node also has a number of basic properties that you can examine or set, including the following:
nodeName—The name of the node (not the ID). For nodes based on HTML tags, such as <p>
or <body>
, the name is the tag name: p
or body
. For the document node, the name is a special code: #document
. Similarly, text nodes have the name #text
. This is a read-only value.
nodeType—An integer describing the node’s type, such as 1
for normal HTML tags, 3
for text nodes, and 9
for the document node. This is a read-only value.
nodeValue—The actual text contained within a text node. This property returns null
for other types of nodes.
innerHTML—The HTML content of any node. You can assign a value including HTML tags to this property and change the DOM child objects for a node dynamically.
Note
The innerHTML
property is not a part of the W3C DOM specification. However, it is supported by the major browsers, and using it is often the easiest way to change content in a page. You can also accomplish this in a more standard way by deleting and creating nodes, as described later on. If your web page must be 100% standards compliant, then you should not use innerHTML
, but in most situations using it is perfectly fine.
In addition to the basic properties described previously, each node has various properties that describe its relationship to other nodes. These include the following read-only properties:
firstChild—The first child object for a node. For nodes that contain text, such as h1
or p
, the text node containing the actual text is the first child.
lastChild—The node’s last child object.
childNodes—An array that includes all of a node’s child nodes. You can use a loop with this array to work with all the nodes under a given node.
previousSibling—The sibling (node at the same level) previous to the current node.
nextSibling—The sibling after the current node.
Caution
Remember that, like all other JavaScript objects and properties, the node properties and functions described here are case sensitive. Be sure you type them exactly as shown.
The document
node itself has several methods you might find useful. You have already used one of them in exercises (getElementById
) to refer to DOM objects by their ID properties. The document
node’s methods include the following:
getElementById(id)—Returns the element with the specified id
attribute.
getElementsByTagName(tag)—Returns an array of all the elements with a specified tag name. You can use the wildcard *
to return an array containing all the nodes in the document.
createTextNode(text)—Creates a new text node containing the specified text, which you can then add to the document.
createElement(tag)—Creates a new HTML element for the specified tag. As with createTextNode
, you need to add the element to the document after creating it. You can assign content within the element by changing its child objects or the innerHTML
property.
Each node within a page has a number of methods available. Which of them are valid depends on the node’s position in the page and whether it has parent or child nodes. These methods include the following:
appendChild(new)—Appends the specified new node after all the object’s existing nodes.
insertBefore(new, old)—Inserts the specified new child node before the specified old child node, which must already exist.
replaceChild(new, old)—Replaces the specified old child node with a new node.
removeChild(node)—Removes a child node from the object’s set of children.
hasChildNodes—Returns the Boolean value true
if the object has one or more child nodes or false
if it has none.
cloneNode—Creates a copy of an existing node. If a parameter of true
is supplied, the copy will also include any child nodes of the original node.
Now that you understand a little more about how the DOM is structured, you should be able to start thinking about how you can control any element in a web page, such as a paragraph or an image. For example, you can use the DOM to change the position, visibility, and other attributes of an element.
Before the W3C DOM and CSS2 standards (remember, we’re now on CSS3), you could only reposition layers, or special groups of elements defined with a proprietary tag. Although you can now position any element individually, it’s still useful to work with groups of elements in many cases.
You can effectively create a layer, or a group of HTML objects that can be controlled as a group, by using the <div>
container element, which you learned about early in these lessons.
To create a layer with <div>
, enclose the content of the layer between the <div>
and </div>
tags and specify the layer’s properties in the style
attribute of the <div>
tag. Here’s a simple example:
<div id="layer1"style="position:absolute; left:100px; top:100px;">
This is the content of the layer.
</div>
This code defines a layer with the name layer1
. This is a movable layer positioned 100 pixels down and 100 pixels to the right of the upper-left corner of the browser window.
Note
As you’ve learned in earlier lessons, you can specify CSS properties such as the position
property and other layer properties in a <style>
block, in an external style sheet, or in the style
attribute of an HTML tag, and you can then control these properties by using JavaScript. The code snippets shown here use properties in the style
attribute rather than in a <style>
block just because it is a snippet of an example and not a full code listing.
You’ve already learned about the positioning properties and seen them in action in Parts II, “Building Blocks of Practical Web Design,” and III, “Advanced Web Page Design with CSS,” of these lessons. This includes setting object size (such as height
and width
) and position (such as absolute
or relative
), object visibility, and object background and borders. The remaining examples in this lesson use HTML and CSS much as you’ve already seen them used but show you JavaScript-based interactions with the DOM in action.
Using the code snippet from the preceding section, in this section you’ll see an example of how you can control the positioning attributes of an object by using JavaScript.
Here is our sample layer (a <div>
):
<div id="layer1"style="position:absolute; left:100px; top:100px;">
This is the content of the layer.
</div>
To move this layer up or down within the page by using JavaScript, you can change its style.top
attribute. For example, the following statements move the layer 100 pixels down from its original position:
var obj = document.getElementById("layer1");
obj.style.top=200;
The document.getElementById
method returns the object corresponding to the layer’s <div>
tag, and the second statement sets the object’s top
positioning property to 200px
; you can also combine these two statements, like so:
document.getElementById("layer1").style.top = 200;
This simply sets the style.top
property for the layer without assigning a variable to the layer’s object.
Note
Some CSS properties, such as text-indent
and border-color
, have hyphens in their names. When you use these properties in JavaScript, you need to combine the hyphenated sections and use camel case: textIndent
and borderColor
.
Now let’s create an HTML document that defines a layer and combine it with a script to allow the layer to be moved, hidden, or shown using buttons. Listing 21.4 shows the HTML document that defines the buttons and the layer. The script itself (position.js
) follows, in Listing 21.5.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Positioning Elements with JavaScript</title>
<style>
#buttons {
text-align:center;
}
#square {
position: absolute;
top: 150px;
left: 100px;
width: 200px;
height: 200px;
border: 2px solid black;
padding: 10px;
background-color: #e0e0e0;
}
div {
padding: 10px;
}
</style>
<meta name="viewport"
content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Positioning Elements</h1>
<div id="buttons">
<button type="button"name="left"
onclick="pos(-1,0);">Left</button>
<button type="button"name="right"
onclick="pos(1,0);">Right</button>
<button type="button"name="up"
onclick="pos(0,-1);">Up</button>
<button type="button"name="down"
onclick="pos(0,1);">Down</button>
<button type="button"name="hide"
onclick="hideSquare();">Hide</button>
<button type="button"name="show"
onclick="showSquare();">Show</button>
</div>
<hr>
<div id="square">
This square is an absolutely positioned layer
that you can move using the buttons above.
</div>
<script src="position.js"></script>
</body>
</html>
In addition to some basic HTML, Listing 21.4 contains the following:
The <style>
section is a brief style sheet that defines the properties for the movable layer. It sets the position
property to absolute
to indicate that it can be positioned at an exact location, sets the initial position in the top
and left
properties, and sets border
and background-color
properties to make the layer clearly visible.
The <button>
tags define six buttons: four to move the layer left, right, up, or down and two to control whether it is visible or hidden.
The <div>
section defines the layer itself. The id
attribute is set to the value "
square
"
. This id
is used in the style sheet to refer to the layer and will also be used in your script.
The <script>
tag right before the </body>
tag reads a script called position.js
, which is shown in Listing 21.5.
If you load the HTML into a browser, you should see the buttons and the "
square
"
layer, but the buttons won’t do anything yet. The script in Listing 21.5 adds the capability to use the actions. When you load the code in Listing 21.4 into your browser, it should look as shown in Figure 21.5.
Listing 21.5 shows the JavaScript variables and functions that are called in the HTML in Listing 21.4. This code is expected (by the <script>
tag) to be in a file called position.js
.
var x=100,y=150;
function pos(dx,dy) {
if (!document.getElementById) return;
x += 30*dx;
y += 30*dy;
obj = document.getElementById("square");
obj.style.top=y + "px";
obj.style.left=x + "px";
}
function hideSquare() {
if (!document.getElementById) return;
obj = document.getElementById("square");
obj.style.display="none";
}
function showSquare() {
if (!document.getElementById) return;
obj = document.getElementById("square");
obj.style.display="block";
}
The var
statement at the beginning of the script defines two variables, x
and y
, that store the current position of the layer. The pos
function is called by the event handlers for all four of the movement buttons.
The parameters of the pos
function, dx
and dy
, tell the script how the layer should move: If dx
is negative, a number is subtracted from x
, moving the layer to the left. If dx
is positive, a number is added to x
, moving the layer to the right. Similarly, dy
indicates whether to move up or down.
The pos
function begins by making sure the getElementById
function is supported, so it won’t attempt to run in older browsers. It then multiplies dx
and dy
by 30 (to make the movement more obvious) and applies them to x
and y
. Finally, it sets the top
and left
properties to the new position (including the px
to indicate the unit of measurement), thus moving the layer.
Two more functions, hideSquare
and show
S
quare
, hide or show the layer by setting its display
property to "
none
"
(hidden) or "
block
"
(shown).
To use this script, save it as position.js
and then load the HTML document in Listing 21.4 into your browser. Figure 21.6 shows this script in action—well, after an action, at least. Figure 21.6 shows the script after the Right button has been clicked four times and the Down button has been clicked five times.
In the preceding example, you saw some functions that can be used to hide or show the “square.” In this section, we’ll take a closer look at hiding and showing objects in a page.
As a refresher, objects have a visibility
style property that specifies whether they are currently visible within the page:
Object.style.visibility="hidden"; // hides an object
Object.style.visibility="visible"; // shows an object
Using this property, you can create a script that hides or shows objects in either browser. Listing 21.6 shows the HTML document for a script that allows two headings to be shown or hidden.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hiding or Showing Objects</title>
<meta name="viewport"
content="width=device-width, initial-scale=1">
</head>
<body>
<h1 id="heading1">This is the first heading</h1>
<h1 id="heading2">This is the second heading</h1>
<p>Using the W3C DOM, you can choose whether to show or hide
the headings on this page using the checkboxes below.</p>
<form name="checkboxform">
<input type="checkbox"name="checkbox1"
onclick="showHide();"checked>
<span style="font-weight:bold;">Show first heading</span><br>
<input type="checkbox"name="checkbox2"
onclick="showHide();"checked>
<span style="font-weight:bold;">Show second heading</span><br>
</form>
<script>
function showHide() {
if (!document.getElementById) return;
var heading1 = document.getElementById("heading1");
var heading2 = document.getElementById("heading2");
var showheading1 = document.checkboxform.checkbox1.checked;
var showheading2 = document.checkboxform.checkbox2.checked;
heading1.style.visibility=(showheading1) ? "visible": "hidden";
heading2.style.visibility=(showheading2) ? "visible": "hidden";
}
</script>
</body>
</html>
The <h1>
tags in this document define headings with the id
s heading1
and heading2
. Inside the <form>
element are two check boxes, one for each of these headings. When a check box is modified (checked
or unchecked
), the onclick
method calls the JavaScript showHide
function to perform an action.
The showHide
function is defined within the <script>
tag at the bottom of the document. This function assigns the objects for the two headings to two variables named heading1
and heading2
, using the getElementById
method. Next, it assigns the value of the check boxes within the form to the showheading1
and showheading2
variables. Finally, the function uses the style.visibility
attributes to set the visibility of the headings.
Note
The lines that set the visibility
property might look a bit strange. The ?
and :
characters create conditional expressions, a shorthand way of handling if
statements. You’ll learn more about these conditional expressions in Lesson 23, “Controlling Flow with Conditions and Loops.”
Figure 21.7 shows this example in action. In the figure, the second heading’s check box has been unchecked, so only the first heading is visible.
You can create a simple script to modify the contents of a heading (or any element, for that matter) within a web page. As you learned earlier in this lesson, the nodeValue
property of a text node contains its actual text, and the text node for a heading is a child of that heading. Thus, this would be how to change the text of a heading with the identifier heading1
:
var heading1 = document.getElementById("heading1");
heading1.firstChild.nodeValue = "New Text Here";
This assigns the heading’s object to the variable called heading1
. The firstChild
property returns the text node that is the only child of the heading, and its nodeValue
property contains the heading text.
Using this technique, it’s easy to create a page that allows the heading to be changed dynamically. Listing 21.7 shows the complete HTML document for a script that does this.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Dynamic Text in JavaScript</title>
<meta name="viewport"
content="width=device-width, initial-scale=1">
</head>
<body>
<h1 id="heading1">Dynamic Text in JavaScript</h1>
<p>Using the W3C DOM, you can dynamically change the
heading at the top of this page.</p>
<p>Enter a new title and click the Change! button. </p>
<form name="changeform">
<input name="newtitle"size="40">
<button type="button"onclick="changeTitle();">Change!</button>
</form>
<script>
function changeTitle() {
if (!document.getElementById) return;
var newtitle = document.changeform.newtitle.value;
var heading1 = document.getElementById("heading1");
heading1.firstChild.nodeValue=newtitle;
}
</script>
</body>
</html>
This example defines a form that enables the user to enter a new heading for the page. Clicking the button calls the changeTitle
function, defined in the <script>
tag at the bottom of the document. This JavaScript function gets the value the user entered in the form and changes the heading’s value to the new text by assigning the value of the input to the heading1.firstChild.nodeValue
property.
Figure 21.8 shows this page in action after a new title has been entered and the Change! button has been clicked.
Next, you can create a script that actually adds text to a page rather than just changing existing text. To do this, you must first create a new text node. This statement creates a new text node with the text “this is a test”:
var node=document.createTextNode("this is a test");
Next, you can add this node to the document. To do this, you use the appendChild
method. The text can be added to any element that can contain text, but in this example, we will just use a paragraph. The following statement adds the text node defined previously to the paragraph with the identifier paragraph1
:
document.getElementById("paragraph1").appendChild(node);
Listing 21.8 shows the HTML document for a complete example that uses this technique, using a form to allow the user to specify text to add to the page.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Adding Text to a Page</title>
<meta name="viewport"
content="width=device-width, initial-scale=1">
</head>
<body>
<h1 id="heading1">Create Your Own Content</h1>
<p id="paragraph1"> Using the W3C DOM, you can dynamically add
sentences to this paragraph.</p>
<p>Type a sentence and click the Add! button.</p>
<form name="changeform">
<input name="sentence"size="65">
<button type="button"onclick="addText();">Add!</button>
</form>
<script>
function addText() {
if (!document.getElementById) return;
var sentence=document.changeform.sentence.value;
var node=document.createTextNode(""+ sentence);
document.getElementById("paragraph1").appendChild(node);
document.changeform.sentence.value="";
}
</script>
</body>
</html>
In this example, the <p>
element with the id
paragraph1
is the paragraph that will hold the added text. The <form>
element is a form with a text field called sentence
, and an Add! button, which calls the addText
function when clicked. This JavaScript function is defined in the <script>
tag at the bottom of the document. The addText
function first assigns text typed in the text field to the sentence
variable. Next, the script creates a new text node containing the value of the sentence
variable and appends the new text node to the paragraph.
Load this document into a browser to test it and try adding several sentences by typing them and clicking the Add! button. Figure 21.9 shows this document after several sentences have been added to the paragraph.
In this lesson, you learned a lot about the Document Object Model (DOM), which creates a hierarchy of web browser and document objects that you can access via JavaScript. You learned how you can use the document
object to work with documents, and you used the history
and location
objects to control the current URL displayed in the browser.
You also learned the methods and properties you can use to manage DOM objects, and you created sample scripts to hide and show elements within a page, modify existing text, and add to existing text. You also learned how to use HTML and CSS to define a positionable layer and how you can use positioning properties dynamically with JavaScript.
This foundational knowledge of the DOM puts you in position (no pun intended) to more effectively work with JavaScript in advanced ways, as you’ll learn in the lessons that follow.
Q. Can I avoid assigning an id
attribute to every DOM object I want to handle with a script?
A. Yes. Although the scripts in this lesson typically use the id
attribute for convenience, you can actually locate any object in the page by using combinations of node properties such as firstChild
and nextSibling
. However, keep in mind that any change you make to the HTML can change an element’s place in the DOM hierarchy, so the id
attribute is a reliable recommended way to handle this.
Q. I can use history
and document
instead of window.history
and window.document
. Can I leave out the window
object in other cases?
A. Yes. For example, you can use alert
instead of window.alert
to display a message. The window
object contains the current script, so it’s treated as a default object. However, be warned that you shouldn’t omit the window
object’s name when you’re using multiple windows or in an event handler.
Q. Can I change history entries or prevent the user from using the Back and Forward buttons?
A. You can’t change the history entries. You also can’t prevent the use of the Back and Forward buttons. However, you can use the location.replace
method to load a series of pages that don’t appear in the history. There are a few tricks for preventing the Back button from working properly, but I don’t recommend using them as they’re the sort of thing that gives JavaScript a bad reputation.
The Workshop contains quiz questions and activities to help you solidify your understanding of the material covered. Try to answer all questions before looking at the “Answers” section that follows.
1. Which of the following DOM objects never has a parent node?
body
div
document
p
2. Which of the following is the correct syntax to get the DOM object for a heading with the identifier heading1
?
document.getElementById(
"
heading1
"
)
document.GetElementByID(
"
heading1
"
)
document.getElementsById(
"
heading1
"
)
documents.getElementsById(
"
heading1
"
)
3. Which of the following tags can be used to create a layer?
<layer>
<div>
<style>
<p>
4. Which property controls an element’s left-to-right position?
left
width
lrpos
position
5. Which of the following CSS rules would create a heading that is not currently visible in the page?
h1 {visibility: invisible;}
h1 {display: none;}
h1 {style: invisible;}
h1 {display: invisible;}
6. What does the document.URL
property do?
Links to the defined URL
Changes the current URL
Specifies the current URL
Nothing. It is invalid.
7. What is nodeValue
?
Any non-text content of a node
The function of the node
The method of the node
The text within a node
8. Does the <body>
tag have a nodeValue
associated with it?
Yes, the number of nodes attached to it
Yes, the value of the child nodes
Yes, but the value is null
No
9. What method takes a child node out of an object?
removeNode
removeChild
deleteChild
deleteNode
10. How can you get the port number for a web page by using JavaScript?
Yes, the number of nodes attached to it
Yes, the value of the child nodes
Yes, but the value is null
No
Note
Just a reminder for those of you reading these words in the print or e-book edition of this book: If you go to www.informit.com/register and register this book (using ISBN 9780672338083), you can receive free access to an online Web Edition that not only contains the complete text of this book but also features an interactive version of this quiz.
1. c. The document
object is the root of the DOM object tree and has no parent object.
2. a. getElementById
has a lowercase g at the beginning and a lowercase d at the end.
3. b. The <div>
tag is one of several container elements that can be used to create positionable layers (but it is the only one in this list that is valid).
4. a. The left
property controls an element’s left-to-right position.
5. b. The none
value for the display
property makes it invisible. The visibility
property could also be used, but its possible values are visible
or hidden
.
6. c. It specifies the current document’s URL and cannot be changed.
7. d. It is the actual text contained within a text node.
8. c. Technically, yes, but the value is null
because it’s not a text node.
9. b. The removeChild
method removes a child node from an object.
10. c. Use the location.port
or location.host
properties to get the port number for a web page.
Modify the example in Listing 21.2 to include a Reload button along with the Back and Forward buttons. (This button would trigger the location.reload
method.)
Modify the positioning example in Listings 21.4 and 21.5 to move the square 1 pixel at a time rather than 30 pixels at a time.
Add a third check box to Listing 21.6 to allow the paragraph of text to be shown or hidden. You need to add an id
attribute to the <p>
tag, add a check box to the form, and add the appropriate lines to the script.
44.211.24.175