So far the discussion has focused primarily on the generic features common to all Document Object Models, regardless of browser version. Not surprisingly, every time a new version was released, browser vendors extended the functionality of the Document object in various ways. Bugs were fixed, access to a greater portion of the document was added, and the existing functionality was continually improved upon.
The gradual evolution of Document Object Models is a good thing in the sense that more recent object models allow you to carry out a wider variety of tasks more easily. However, it also poses some major problems for Web developers. The biggest issue is that the object models of different browsers evolved in different directions. New, proprietary tags were added to facilitate the realization of Dynamic HTML (DHTML) and new, non-standard means of carrying out various tasks became a part of both Internet Explorer and Netscape. This means that the brand-new DHTML code a developer writes using the Netscape object model probably will not work in Internet Explorer (and vice versa). Fortunately, as the use of older browsers continues to dwindle and modern browsers improve their support for DOM standards, we won’t have to know these differences forever and will be free to focus solely on the ideas of Chapter 10. However, for now, readers are encouraged to understand the object models, and particular attention should be paid to the later Internet Explorer models, since many developers favor it over DOM standards for better or worse.
The object model of the first JavaScript browser, Netscape 2, is that of the basic object model presented earlier in the chapter. It was the first browser to present such an interface to JavaScript and its capabilities were limited. The main use of JavaScript in this browser because of its limited object model is form validation and very simple page manipulation, such as printing the last date of modification. Netscape 3’s Document object opened the door for the first primitive DHTML-like applications. It exposes more of document content to scripts by providing the ability to access embedded objects, applets, plug-ins, and images. This object model is shown in Figure 9-5 and the major additions to the Document object are listed in Table 9-4.
Property |
Description |
---|---|
applets[] |
Array of applets (<applet> tags) in the document |
embeds[] |
Array of embedded objects (<embed> tags) in the document |
Array of images (<img> tags) in the document |
|
plugins[] |
Array of plug-ins in the document |
Note |
The Netscape 3 object model without the embeds[] and plugins[] collections is the core of the DOM Level 0 standard and thus is quite important to know. |
Arguably, for many Web developers the most important addition to the Document object made by Netscape 3 was the inclusion of the images[] collection, which allowed for the now ubiquitous rollover button discussed in Chapter 15.
The Document Object Model of version 4 browsers marks the point at which support for so-called Dynamic HTML (DHTML) begins. Outside of swapping images in response to user events, there was little one could do to bring Web pages alive before Netscape 4. Major changes in this version include support for the proprietary <<layer>> tag, additions to Netscape’s event model, and the addition of Style objects and the means to manipulate them. Figure 9-6 shows the essentials of Netscape 4’s object model, and the most interesting new properties of the Document object are listed in Table 9-5.
Property |
Description |
---|---|
classes |
Creates or accesses CSS style for HTML elements with class attributes set. |
Ids |
Creates or accesses CSS style for HTML elements with id attributes set. |
layers[] |
Array of layers (<layer> tags or positioned <div> elements) in the document. |
tags |
Creates or accesses CSS style for arbitrary HTML elements. |
While most of the aspects of the Netscape 4 object model, are regulated to mere historical footnotes in Web development, one aspect of this generation of browsers that continues to plague developers is the proprietary Layer object.
Netscape 4 introduced a proprietary HTML tag, <<layer>>, which allowed developers to define content areas that can be precisely positioned, moved, overlapped, and rendered hidden, visible, or even transparent. It would seem that <<layer>> should be ignored since it never made it into any W3C’s HTML standard, was never included by any competing browser vendors, and it was quickly abandoned in the 6.x generation of Netscape. Yet its legacy lives on for JavaScript developers who need to use the document.layers[] collection to access CSS positioned <<div>> regions in Netscape 4. To this day, many DHTML libraries and applications support document.layers[] for better or for worse. As a quick example of Netscape 4’s Layer object we present an example of hiding and revealing a CSS positioned region.
<<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">> <<html>> <<head>> <<title>>NS4 Layer Example<</title>> <<style type="text/css">> <<!-- #div1 { position: absolute; top: 200px; left: 350px; height: 100px; width: 100px; background-color: orange;} -->> <</style>> <</head>> <<body>> <<h1 align="center">>Netscape 4 Layer Example<</h1>> <<div id="div1">>An example of a positioned region<</div>> <<form action="#" method="get">> <<input type="button" value="hide" onclick="document.layers['div1'].visibility='hide';">> <<input type="button" value="show" onclick="document.layers['div1'].visibility='show';">> <</form>> <</body>> <</html>>
One wrinkle with this collection is that only the first level of nested layers is available via document.layers[] because each layer receives its own Document object. To reach a nested layer, you must navigate to the outer layer, through its Document to the nested layer’s layers[] array, and so on. For example, to reach a layer within a layer you might write
var nestedLayer = document.layers[0].document.layers[0].document;
Although the use of the Layer object hopefully will be gone forever in the near future, for backward compatibility to Netscape 4.x generation browsers, they are required. Interested readers should note that Chapter 15 presents a cross-browser DHTML library that will help address just such problems.
The release of Netscape 6 marked an exciting, but short era for Netscape browsers. While ultimately the Netscape browser itself died off, the engine and browser it was based upon, Mozilla, continues to live on in many forms. The main emphasis of this browser family is standards compliance, a refreshing change from the ad hoc proprietary Document Object Models of the past. It is backward compatible with the so-called DOM Level 0, the W3C’s DOM standard that incorporates many of the widespread features of older Document Object Models, in particular that of Netscape 3. However, it also implements DOM Level 1 and parts of DOM Level 2, the W3C’s object models for standard HTML, XML, CSS, and events. These standard models differ in significant ways from older models, and are covered in detail in the following chapter.
Support for nearly all of the proprietary extensions supported by older browsers like Netscape 4, most notably the <<layer>> tag and corresponding JavaScript object, have been dropped since Netscape 6. This breaks the paradigm that allowed developers to program for older browser versions knowing that such code will be supported by newer versions. Like many aspects of document models, this is both good and bad. Older code may not work in Netscape/Mozilla-based browsers, but future code written toward this browser will have a solid standards foundation. Readers unfamiliar with the Mozilla (www.mozilla.org) family of browsers are encouraged to take a look as they may find new and exciting changes as well as the opportunity to safely test many of the emerging W3C markup, CSS, and DOM standards discussed in Chapter 10.
The object model of IE3 is the basic “lowest common denominator” object model presented at the beginning of this chapter. It includes several “extra” properties in the Document object not included in Netscape 2, for example, the frames[] array, but for the most part it corresponds closely to the model of Netscape 2. The Internet Explorer 3 object model is shown in Figure 9-7.
For the short period of time when Netscape 2 and IE3 coexisted as the latest versions of the respective browsers, object models were in a comfortable state of unity. It wouldn’t last long.
Like version 4 of Netscape’s browser, IE4 lays the foundations for DHTML applications by exposing much more of the page to JavaScript. In fact, it goes much further than Netscape 4 by representing every HTML element as an object. Unfortunately, it does so in a manner incompatible with Netscape 4’s object model. The basic object model of Internet Explorer 4 is shown in Figure 9-8.
Inspection of Figure 9-8 reveals that IE4 supports the basic object model of Netscape 2 and IE3, plus most of the features of Netscape 3 as well as many of its own features. Table 9-6 lists some important new properties found in IE4. You will notice that Figure 9-9 and Table 9-6 show that IE4 also implements new document object features radically different from those present in Netscape 4. It is in version 4 of the two major browsers where the object models begin their divergence.
Property |
Description |
---|---|
>all[] |
Array of all HTML tags in the document |
>applets[] |
Array of all applets (<applet> tags) in the document |
>children[] |
Array of all child elements of the object |
>embeds[] |
Array of embedded objects (<embed> tags) in the document |
>images[] |
Array of images (<img> tags) in the document |
>scripts[] |
Array of scripts (<script> tags) in the document |
>styleSheets[] |
Array of Style objects (<style> tags) in the document |
One of the most important new JavaScript features introduced in IE4 is the document.all collection. This array provides access to every element in the document. It can be indexed in a variety of ways and returns a collection of objects matching the index, id, or name attribute provided. For example:
// sets variable to the fourth element in the document var theElement = document.all[3]; // finds tag with id or name = myHeading var myHeading = document.all["myHeading"]; // alternative way to find tag with id or name = myHeading var myHeading = document.all.item("myHeading"); // returns array of all <<em>> tags var allEm = document.all.tags("EM");
As you can see, there are many ways to access the elements of a page, but regardless of the method used, the primary effect of the document.all collection is that it flattens the document object hierarchy to allow quick and easy access to any portion of an HTML document. The following simple example shows that Internet Explorer truly does expose all the elements in a page; its result is shown in Figure 9-9.
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">> <<html xmlns="http://www.w3.org/1999/xhtml">> <<head>> <<title>>Document.All Example<</title>> <<meta http-equiv="content-type" content="text/html; charset=utf-8" />> <</head>> <<body>> <<h1>>Example Heading<</h1>> <<hr />> <<p>>This is a <<em>>paragraph<</em>>. It is only a <<em>>paragraph.<</em>><</p>> <<p>>Yet another <<em>>paragraph.<</em>><</p>> <<p>>This final <<em>>paragraph<</em>> has <<em id="special">>special emphasis.<</em>><</p>> <<hr />> <<script type="text/javascript">> <<!-- var i,origLength; origLength = document.all.length; document.write('document.all.length='+origLength+"<<br />>"); for (i = 0; i << origLength; i++) { document.write("document.all["+i+"]="+document.all[i].tagName+"<<br />>"); } //-->> <</script>> <</body>> <</html>>
Once a particular element has been referenced using the document.all syntax, you will find a variety of properties and methods associated with it, including the all property itself, which references any tags enclosed within the returned tag. Tables 9-7 and 9-8 show some of the more interesting, but certainly not all of these new properties and methods. Note that inline elements will not have certain properties (like innerHTML) because by definition their tags cannot enclose any other content.
Property |
Description |
---|---|
>all[] |
Collection of all elements contained by the object. |
>children[] |
Collection of elements that are direct descendents of the object. |
>className |
String containing the CSS class of the object. |
>innerHTML |
String containing the HTML content enclosed by, but not including, the object's tags. This property is writeable for most HTML elements. |
>innerText |
String containing the text content enclosed by the object's tags. This property is writeable for most HTML elements. |
>outerHTML |
String containing the HTML content of the element, including its start and end tags. This property is writeable for most HTML elements. |
>outerText |
String containing the outer text content of the element. This property is writeable for most HTML elements. |
>parentElement |
Reference to the object's parent in the object hierarchy. |
>style |
Style object containing CSS properties of the object. |
>tagName |
String containing the name of the HTML tag associated with the object. |
Method |
Description |
---|---|
>click() |
Simulates clicking the object causing the onClick event handler to fire |
>getAttribute() |
Retrieves the argument HTML attribute for the element |
>insertAdjacentHTML() |
Allows the insertion of HTML before, after, or inside the element |
>insertAdjacentText() |
Allows the insertion of text before, after, or inside the element |
>removeAttribute() |
Deletes the argument HTML attribute from the element |
>setAttribute() |
Sets the argument HTML attribute for the element |
If Tables 9-7 and 9-8 seem overwhelming, do not worry. At this point, you are not expected to fully understand each of these properties and methods. Rather, we list them to illustrate just how far the Netscape and Internet Explorer object models diverged in a very short period of time. We’ll cover the DOM-related properties IE supported in the next chapter as well as a few of the more useful proprietary features. The balance will be covered in Chapter 21 and Appendix B.
However, even brief examination of the features available in Internet Explorer should reveal that this is the first browser where real dynamic HTML is possible, providing the means to manipulate style dynamically and to insert, modify, and delete arbitrary markup and text. For the first time, JavaScript can manipulate the structure of the document, changing content and presentation of all aspects of the page at will. The following example illustrates this idea using Internet Explorer–specific syntax.
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">> <<html xmlns="http://www.w3.org/1999/xhtml">> <<head>> <<title>>Document.All Example #2<</title>> <<meta http-equiv="content-type" content="text/html; charset=utf-8" />> <</head>> <<body>> <<!-- Works in Internet Explorer and compatible -->> <<h1 id="heading1" align="center" style="font-size: larger;">>DHTML Fun!!!<</h1>> <<form name="testform" id="testform" action="#" method="get">> <<br />><<br />> <<input type="button" value="Align Left" onclick="document.all['heading1'].align='left';" />> <<input type="button" value="Align Center" onclick="document.all['heading1'].align='center';" />> <<input type="button" value="Align Right" onclick="document.all['heading1'].align='right';" />> <<br />><<br />> <<input type="button" value="Bigger" onclick="document.all['heading1'].style.fontSize='xx-large';" />> <<input type="button" value="Smaller" onclick="document.all['heading1'].style.fontSize='xx-small';" />> <<br />><<br />> <<input type="button" value="Red" onclick="document.all['heading1'].style.color='red';" />> <<input type="button" value="Blue" onclick="document.all['heading1'].style.color='blue';" />> <<input type="button" value="Black" onclick="document.all['heading1'].style.color='black';" />> <<br />><<br />> <<input type="text" name="userText" id="userText" size="30" />> <<input type="button" value="Change Text" onclick="document.all['heading1'].innerText=document.testform.userText.value;" />> <</form>> <</body>> <</html>>
The previous examples given here barely scratch the surface of IE’s powerful Document Object Model that started first with Internet Explorer 4 and only increased in capability in later releases.
The Document Object Model of Internet Explorer 5.x and 6.x is very similar to that of IE4. New features include an explosive rise in the number of properties and methods available in the objects of the document model and proprietary enhancements allowing the development of reusable DHTML components. Internet Explorer 5.5 continued the trend of new features, and by Internet Explorer 6, we see that IE implements significant portions of the W3C DOM. However, often developers may find that to make IE6 more standards-compliant they must be careful to “switch on” the standards mode by including a valid DOCTYPE. Yet even when enabled, the IE5/5.5/6 implementation is simply not a 100 percent complete implementation of the W3C DOM and there are numerous proprietary objects, properties, and methods that are built around the existing IE4 object model. Furthermore, given the browser’s dominant position, many of its ideas like document.all and innerHTML seem to be more accepted by developers than standards’ proponents would care to admit.
Although rarely considered by some Web developers, there are some other browsers that have a small but loyal following in many tech-savvy circles. Most third-party browsers are “strict standards” implementations, meaning that they implement W3C and ECMA standards and ignore most of the proprietary object models of Internet Explorer and Netscape. Most provide support for the traditional JavaScript object model and embrace the fact that Internet Explorer–style JavaScript is commonplace on the Web. However, at their heart, the alternative browsers focus their development efforts on the W3C standards. If the demographic for your Web site includes users likely to use less common browsers, such as Linux aficionados, it might be a good idea to avoid IE-specific features and use the W3C DOM instead.