In Part I we introduced portions of the Document Object Model (DOM), which provides a scriptable interface for a document structure. With the DOM, an HTML document is described as a series of nodes, each node representing an object in the document, including all text, tags, comments, and other data. Altering these nodes through JavaScript, a developer can alter the visual display of the page in a browser. If you read the last article you know how to use DOM methods to create, insert, and remove elements and text nodes from the page.
This article dives a little deeper into the JavaScript node interface and examines the different ways of altering the visible properties of an element or text node. Youll first learn how to alter element attributes with DOM element methods, then youll see how to change an elements style properties through the DOM Level 2 (DOM2) Style specification interface.
Getting an Element Reference
Before you use the DOM interface to manipulate element nodes, you will need to get a reference to the element with which you want to work. By reference I mean a variable that points to the correct object in the page. You may already be familiar with document.images, document.forms, and other collections available in most browsers. These collections are groups of references to objects within the page. If you needed a reference to an image with the NAME attribute of imgHeader, you could use the images collection to grab the correct element by its name:
var img = document.images["imgHeader"];
However, these collections are only available to a subset of a pages elements. For example, there is no document.tables or document.paragraphs collection that allows you to get references to those classes of elements.
Fortunately, the DOM2 interface provides two methods to help get a hold of any element (and hold onto it tightly believe me, elements can be slippery). These two methods are:
document.getElementById(string id): returns a reference to the element with the specified ID.
document.getElementsByTagName(string tagName): returns a collection (array) of all elements of the specified tag name.
Thus, to get a reference to a table element with an ID of tableMain, you could use the following line of JavaScript:
var table = document.getElementById("tableMain");
The variable table should now contain a reference to the appropriate table. getElementById() assumes the element in question has an ID attribute to match against. If no element with a matching ID is found, getElementById returns a null value.
Its important to realize that the NAME attribute of an element is not the same as its ID. For example, if youre in the habit of assigning NAME attributes to your image tags, you cannot access them with getElementById unless you also include an ID attribute. Its perfectly fine to have elements with identical NAME and ID values.
getElementsByTagName() is useful for situations where you need references to all elements of a particular type. This method returns a collection containing a reference to each matching element it finds. For example, if you we wanted to count the number of table cells in the page, you could use something like the following code:
var allTDs = document.getElementsByTagName("td");
alert("# of table cells: " + allTDs.length);
Try it out. Click the button below to use getElementsByTagName() to count the number of table cells in this page.
To get a particular element reference in the collection, use the collections item() method, which returns a reference to the element at the specified index. If you wanted to get a reference to the first and last table cells in the collection, you could use this:
var allTDs = document.getElementsByTagName("td");
var firstTD = allTDs.item(0).id;
var lastTD = allTDs.item(allTDs.length-1).id;
var str = "# of table cells: " + allTDs.length + "\n";
str += "First TD: " + firstTD + "\n";
str += "Last TD: " + lastTD;
alert(str);
The advantage of using item() instead of directly referencing the slot in the collection is that item() returns a null value if the index supplied is invalid or the element in question is not within the collection. This is often more desirable than the error message you might get when referencing a nonexistent slot in the collection.
getElementsByTagName() is also a method of every element, which means you can retrieve a collection of references to all elements within a particular element. The following code uses getElementsByTagName() at the element level to retrieve references to all images within a table:
var table = document.getElementById("myTable");
var imgs = table.getElementsByTagName("img");
Once you have an element reference, you can manipulate its properties.
Reading and Setting Element Attributes
Element tag attributes are translated by the browser into properties of the object (the reference youve created). The DOM interface provides each element with two methods for reading and setting these attribute values:
getAttribute(string name): returns the value of the attribute specified by the name argument
setAttribute(string name, string value): adds a new attribute of the specified name and value, or sets the existing attribute to the specified value.
I often like to use a utility function to inspect an element and see the properties and methods attached to it. The inspect() function seen below uses getElementById() to retrieve a reference to the element and launch an alert box containing a list of the element properties. The string of properties and values is assembled using getAttribute() to retrieve the value of each named property.
function inspect(elm){
var str = "";
for (var i in elm){
str += i + ": " + elm.getAttribute(i) + "\n";
}
alert(str);
}
To use the inspect() function to examine a table element, simply pass the table element to the function:
Want to see it in action? Click the button to inspect the table below.
one
two
three
four
five
six
seven
eight
nine
Setting new element properties can be done with the setAttribute() method. Just pass the name and the value of the attribute you want to set. Note that both parameters must be strings, so even numeric values must be within quotes. To readjust the width of a table to 400 pixels, you can employ the following code:
var table = document.getElementById("tableMain");
table.setAttribute("width","400");
The following example uses setAttribute() and the changeSize() to assign different values to this tables WIDTH attribute.
function changeSize(px){
var table = document.getElementById("tableMain2");
table.setAttribute("width",px);
}
one
two
three
four
five
six
seven
eight
nine
If no attribute of the specified name exists for the element, setAttribute() will create a new one. Theres really no inherent advantage to using setAttribute() over directly setting the value via JavaScript. The following two statements essentially accomplish the same thing:
table.setAttribute("border","2");
table.border = 2;
To prevent new attributes from being set where you dont want them, you can use the element method hasAttribute() to test for the existence of the named attribute. hasAttribute() returns either true or false depending upon whether the element possesses the attribute or not.
var table = document.getElementById("tableMain");
if (table.hasAttribute("border")){
table.setAttribute("border","2");
} else {
alert("Table has no border");
}
It should be noted that hasAttribute() is supported in Netscape 6/Mozilla, but not IE5 at the time this article was composed.
Manipulating Element Styles
So far, Ive only talked about manipulating element attributes. Often, an element will employ CSS to give it a particular style or formatting. Altering the CSS properties of an element requires a similar yet slightly different approach.
The DOM specification provides another interface called DOM Level 2 Style, which is for manipulating the CSS properties of an element. Each CSS rule for an element is represented as a property of the elements style object.
Because style is an object, we can examine its properties with a function similar to inspect(), above. The inspectStyle() function below checks the element in question for a style object before proceeding to inspect its values. As we discovered in Modifying Styles, a bug in the current releases of Netscape 6 and Mozilla prevents CSS rules in an inline stylesheet from populating the style object correctly in those browsers. So for the sake of this demonstration, all element CSS has been defined within the tags themselves via the STYLE attribute.
function inspectStyle(elm){
if (elm.style){
var str = "";
for (var i in elm.style){
str += i + ": " + elm.style[i] + "\n";
}
alert(str);
}
}
var header = document.getElementById("h2");
inspectStyle(header);
Click the button below to view the style properties of the H2 element below. Note: some users of IE 5.1 Preview for Mac OS X have expirenced problems with this script.
Headline Here
Youll notice that many of the style properties are empty, since we havent defined them to be otherwise. You can set style properties directly. To read and then set the background color of an HTML page (or specifically, the background color of the BODY element):
var doc = document.getElementsByTagName("body").item(0);
var color = doc.style.backgroundColor;
alert ("Background color is: " + color);
doc.style.backgroundColor = "#0000ff";
Manipulating the CSS properties of elements is key to DHTML functionality. For example, you can use JavaScript to change the tables LEFT and BACKGROUND-COLOR CSS properties, thus changing its color and position on the page. Try it out:
one
two
three
four
five
six
seven
eight
nine
Change Position:
Change Color:
Heres the JavaScript that makes it happen. In all cases, the table ID, tableMain3 is passed to getElementById() in order to get a reference to the table element. The new CSS property value is assigned directly to the style object.
<span class="sourcecode">
<script language="JavaScript" type="text/javascript">
function tableRight(){
var table = document.getElementById("tableMain3");
table.style.left = "100px";
}
function tableLeft(){
var table = document.getElementById("tableMain3");
table.style.left = "0px";
}
function changeTColor(col){
var table = document.getElementById("tableMain3");
table.style.backgroundColor = col;
}
To get the name of the scriptable style property, take the original style rule from the CSS declaration and capitalize the first letter following each hyphen, then remove the hyphens altogether. The following table contains a few examples:
CSS property
JavaScript equivalent
background-color
style.backgroundColor
font-size
style.fontSize
left
style.left
border-top-width
style.borderTopWidth
From Here
This concludes our brief tour of the Document Object Model. Weve touched on some of the more exciting features of the DOM, including dynamic element creation and setting element attributes and CSS properties through JavaScript. The DOM interface has many more features we didnt explore in these articles; I encourage you to check out the specification at the W3C site, specifically the ECMAScript bindingspages which describe the DOM Level 2 Core and Style scripting interface in more detail. Be sure to check your browsers documentation to see what DOM features it supports.
At this point you may want to jump to some of the Internet Developer articles that deal with the DOM, such as Navigator 6 DHTML and Modifying Styles, both of which deal with the complexities of altering a document display through scripting.