Accessing Elements through DOM In DHTML

We can access an element (e.g., a layer) by it’s ID with document.getElementById(ID). We can also access element nodes with document.getElementsByTagName(tagName). That returns an array of elements with that tagName.
 
Example: document.getElementsByTagName(“TD”).item(0)
 

In the example, we grab the first table cell (<td> tag) in the document. To get an array of all tags in the document, we can use:

 

document.getElementsByTagName(“*”)

 
So, to access the <body> tag, we can use:
 
document.getElementsByTagName(“BODY”).item(0)
 
Before applying the information provided in the past two sections, it’s important to recognize two caveats.
 
1. You cannot realistically reference document nodes by anything other than the id attribute in HTML(XML is OK). IE5 and NS6 both insert spurious text nodes between the ones you have written (NS6 more than IE5).
 
2. <p> elements cannot be stacked according to the HTML 4.01 specification. As stated by the W3C, “The P element represents a paragraph. It cannot contain block-level elements (including P itself).”
 
What he means is that it’s really unrealistic to access an element by using it’s relation to another one (with parentNode, firstChild, previousSibling, etc…). And lastly, he is saying that <p> elements should not be contained within another <p> element.
 
An example
 
Let’s look at an example of referencing each element in different ways.
 
Consider this page:
 
   <body>

   <ol id="ol1">

           <li id="li1">

                 <span id="span1">This is Line 1   </span>

             </li>

            <li id="li2">

				<span id="span2">This is Line 2</span>

			</li>

            <li id="li3">

             <span id="span3">                   This is Line 3             </span>

             </li>

   </ol>

</body>

 
Now, we can access the ol1 tag by a number of ways (remember, these may be
 
ineffective because of “spurious text nodes”):
 
• document.getElementById(“ol1”)
• document.getElementsById(“li1”).parentNode
• document.getElementsByTagName(“ol”).item(0)
• document.getElementsByTagName(“li”).item(0).parentNode
• document.getElementsByTagName(“li”).item(1).parentNode
• document.getElementsByTagName(“l1”).item(2).parentNode
• document.getElementsByTagName(“span”).item(2).parentNode.parentNode
• document.getElementsByTagName(“body”).item(0).childNodes.item(0)
• document.body.childNodes.item(0)
 
Because we’ll probably access the <body> tag a lot, we can use a shortcut (rather than using it’s tagName like this: document.getElementsByTagName(“BODY“).item(0) or by assigning it an ID and using that):
 
document.body as used above.
 
To access l2, we could use:
 
• document.getElementById(“l2”)
• document.getElementById(“l1”).nextSibling
• document.getElementById(“l3”).previousSibling
• document.getElementsByTagName(“li”).item(1)
• document.getElementsByTagName(“span”).item(1).parentNode
• document.getElementsByTagName(“span”).item(2).parentNode.previous Sibling
•document.getELementsByTagName(“ol”).childNodes.item(1).parentNode.
childNodes.item(1).parentNode.childNodes.item(1) document.getElementsByTagName(“body”).item(0).firstChild.firstChild.nextSibling
• document.body.childNodes.item(0).lastChild.previousSibling
 
Try to find the text node containing the following text–“This is Text 3.”
 
We could find it by first accessing span3, and then accessing it’s firstChild. Example:
 
document.getElementById(“span3”).firstChild
 
Before, I said attributes were somewhat nodes. This is why they don’t show up when you try to access an element’s child nodes. Later, we’ll look at how to change, set, and remove attributes; but before that, let’s move on to some other essentials we can access from an element node.
 
Level 0 DOM
 
The Level 0 DOM was invented by Netscape at the same time JavaScript was invented and was first implemented in Netscape 2. It offers access to a few HTML elements, most importantly forms and (later) images.
 
For reasons of backward compatibility the more advanced browsers, even those who support the Level 1 DOM, still also support the old, faithful Level 0 DOM. Not supporting it would mean that the most common scripts suddenly wouldn’t work any more. So even though the Level 0 DOM doesn’t entirely fit into the new DOM concepts, browsers will continue to support it.
 
For the same reason Microsoft was at first forced to copy the Netscape DOM for Explorer 3. They wanted a real competitor for Netscape and having it produce lots of error messages on every page that contained JavaScript would have been strategically unsound.
 
Therefore the Level 0 DOM is really unified: all browsers that support parts of it support these parts in the same way. With the later DOMs this situation changed.
 
Intermediate DOMs
 
When the Version 4 browsers were released, the hype of the day was DHTML so both browsers had to support it. DHTML needs access to layers, separate parts of a page that can be moved across the page. Not surprisingly in view of their increasing competition, Netscape and Microsoft chose to create their own, proprietary DOMs to provide access to layers and to change their properties (their position on the page, for instance).
 
Netscape created the layer model and the DOM document.layers, while Microsoft used document.all. Thus a proper cross-browser DHTML script needs both intermediate DOMs.
 
Fortunately, nowadays these intermediate DOMs are not important any more. You can safely forget them.
 
Level 1 DOM
 
Meanwhile W3C had developed the Level 1 DOM specification. The Document Object Model W3Cproposed was at first written for XML documents, but since HTML is after all a sort of XML, it could serve for browsers too.
 
Besides, the Level 1 DOM is a real advance. For the first time, a DOM was not only supposed to give an exact model for the entire HTML (or XML) document, it is also possible to change the document on the fly, take out a paragraph and change the layout of a table, for instance.
 
Since both Netscape and Microsoft had participated in the specification of the new DOM, since both browser vendors wanted to support XML in their version 5 browser and since public pressure groups like the Web Standards Project exhorted them to behave sensibly just this once, both decided to implement the Level 1 DOM.
 
Of course, this doesn’t mean that Mozilla and Explorer 5 are the same. Again for reasons of backward compatibility Microsoft decided to continue support of document.all so that Explorer 5 now supports two DOMs (three if you count the Level 0 DOM).
 
On the other hand, the core of Mozilla is being built by the open source Mozilla Project and the leaders of this project have decided to completely ditch the old document.layers DOM of Netscape 4 and have Mozilla support only the Level 1 DOM.
 
Accessing elements
 
Each DOM gives access to HTML elements in the document. It requires you, the web programmer, to invoke each HTML element by its correct name. If you have done so, you can influence the element (read out bits of information or change the content or layout of the HTML element).
 
For instance, if you want to influence the image with name=”first” you have to invoke it by its proper name and you are granted access. The Level 0 DOM supports the following nodeLists:
 
document.images[‘first’]
 
• document.images[], which grants access to all images on the page.
• document.forms[], which grants access to all forms on the page.
• document.forms[].elements[], which grants access to all form fields in one form, whatever their tag name. This nodeList is unique to the Level 0 DOM; the W3C DOM does not have a similar construct.
• document.links[], which grants access to all links (<a href>) on the page.
• document.anchors[], which grants access to all anchors (<a name>) on the page.
 
How to use the Level 0 DOM
 
When the browser concludes that an HTML document has been completely loaded, it starts making arrays for you. It creates the array document.images[] and puts all images on the page in it, it creates the array document.forms[] and puts all forms on the page in it etc.
 
This means that you now have access to all forms and images, you just have to go through the array in search of the exact image or form that you want to influence. This can be done in two ways: by name or by number.
 
Suppose you have this HTML document:
 
-------------------------------------------

|                document                 |

| --------         -------------------    |

| |img   |         |   second image  |    |

| --------         |                 |    |

|                  -------------------    |

|  -------------------------------------  |

|  |             form                  |  |

|  | ---------------------             |  |

|  | |      address      |             |  |

|  | ---------------------             |  |

|  -------------------------------------  |

-------------------------------------------

 
document.images
 
The first image has name=”thefirst”, the second has name=”thesecond”. Then the first image can be accessed by either of these two calls:
 
document.images[‘thefirst’]
document.images[0]
 
The second one can be accessed by either of these calls:
 
document.images[‘thesecond’]
document.images[1]
 
The first call is by name, simply fill in the name (between quotes, it’s a string!) within the [] and you’re ready.
 
The second call is by number. Each image gets a number in the document.images array, in order of appearance in the source code. So the first image on a page is document.images[0], the second one is document.images[1] etc.
 
document.forms
 
The same goes for forms. Suppose the form on the page has name=”contactform”, then you can reach it by these two calls:
 
document.forms[‘contactform’]
document.forms[0]
 
But in the case of forms, usually you don’t want to access just the form, but a specific form field. No problem, for each form the browser automatically creates the array document.forms[].elements[] that contains all elements in the form.
 
The form above holds as first element an <input name=”address”>. You can access it by these four calls:
 
document.forms[‘contactform’].elements[‘address’] document.forms[‘contactform’].elements[0]
document.forms[0].elements[‘address’]
document.forms[0].elements[0]
 
These four calls are completely interchangeable, it’s allowed to first use one, then another. It depends on your script exactly which method of access you use.
 
Doing what you need to do
 
Once you have correctly accessed a form field or an image through the Level 0 DOM, you’ll have to do what you want to do. Images are usually accessed to create a mouseover effect that changes the property src of an image:
 
document.images[‘thefirst’].src = ‘another_image.gif’;
 
Usually you want to access forms to check what a user has filled in. For instance to read out what the user has filled in check the property value:
 
x = document.forms[0].elements[0].value;
 
and then check x for whatever is necessary.