Path // www.yourhtmlsource.comJavaScript → ADVANCED DOMS

Advanced DOMs


You’ve already seen the Level 0 DOM being used to gain access to some of the basic objects and properties on your page, but to build truly dynamic scripts, we’ll need to be able to access more than images, links and form elements. We need access to every element on the page. There are three advanced Document Object Models which will help us out here, all explained below.

Clock This page was last updated on 2012-08-21



The Rise of a new DOM

When JavaScript was first implemented in Netscape 2, all those years ago, the first Document Object Model came with it. This is now known as the Level 0 DOM, a basic model by today’s standards, but it does the job. It is constrained to providing access to images, form fields, links and anchors. All JavaScript-supporting browsers also support this DOM.

However, if we want to gain access to things like specific paragraphs, tables or headings; the Level 0 model comes up short. When Dynamic HTML (changing style declarations through JavaScript) came onto the scene at around the time of the version 4 browsers, there was an instant need to be able to get access to the style properties of any and all HTML elements on the page.

To this end, each of the big two browser companies (Netscape and Microsoft) came up with their own proprietary DOMs; which work differently and are not commonly supported by any stretch of the imagination:

  • Microsoft created the document.all model for IE4+, a pretty decent design.
  • Netscape designed the document.layers model for Navigator 4. It’s a poor, complicated DOM that thankfully was only supported until Netscape 6 in favour of the W3C-designed Level 1 DOM.
  • Yep, there’s yet another possible DOM: the Level 1 DOM. Since we can’t be coding for two different models for all eternity, the » W3C stepped in and designed the » Level 1 DOM. This is the DOM for the future, which already enjoys very good support in modern browsers. Until old browsers go away completely, some of us will continue to use all three DOMs so as to leave legacy support in our scripts for the benefit of users of old non-compliant browsers.

The Level 1 DOM

Browser Compatibility Note:

The standardised Level 1 DOM is supported by Firefox, Mozilla, Internet Explorer 5+, Opera 7+, Safari, Konqueror and iCab.

May as well start with the one that has a future, eh? Accessing elements in these advanced DOMs isn’t too tricky; it’s just the fact that you have to say the same thing three different ways all the time that makes it awkward.

The Level 1 DOM is very straightforward. First, give the HTML element you want to get access to an id attribute, like this:

<p id="introduction">
<i>Once upon a time...</i>
</p>

The necessary restriction of the id attribute is that only one element on the page can have each specific value. This means the browser will always know which element you’re referring to. If the example above was to be used, you couldn’t have another element with an id value of “introduction” on the page.

Now, through the Level 1 DOM, we access this element by passing this id to the “get element by id” method, like this:

document.getElementById('introduction')

This gives us access to the element. See, it wasn’t hard, we’re getting the element by its id, just as it says. The DOM is vital for DHTML, so to see some working examples, have a look at DHTML Explained.

document.all

Browser Compatibility Note:

Microsoft’s DOM was designed for Internet Explorer 4. Because a lot of lazy webmasters wrote scripts that only use this DOM, with no code for other DOM systems, other browser developers added support for it in their browsers, among them Firefox, Opera 6, iCab, and Omniweb. Future versions of IE look likely to continue to support it alongside the Level 1 DOM to preserve backwards-compatibility.

The Internet Explorer-specific DOM is quite similar to the new W3C model (there’s some politics behind this, but you don’t really want to hear about that). Again, id values are used to get access, with only the method keyword changing, and the parentheses being replaced with brackets:

document.all['introduction'].style.color = 'red';

This DOM had lots of interesting methods built into it, but due to a lack of documentation, much of this DOM’s power has been left undiscovered. All that doesn’t really matter, since the W3C DOM is still being actively developed, and will have new capabilities built into it in future “Levels.”

document.layers

Dear oh dear. I’m sure a lot of web designers would like to sit down and have a friendly chat with the developers that came up with Netscape’s DOM. Quite apart from its questionable structure, it was also implemented very poorly in Netscape’s own browser and was afflicted by a number of bugs. Praise be, then, that Netscape (and Mozilla, makers of Firefox) have taken the admirable step of jettisoning support for this model in their new browsers.

Still, there continue to exist project managers that insist on Netscape 4 compatibility for their websites. This will happen less and less, until eventually document.layers will only be mentioned when wispy-bearded web designers get together to talk about the “bad old days.” For the benefit of those poor coders forced to support this detritus, here are the gory details:

  • While Netscape introduced a new <layer> element specifically to create “layers” (areas that can move independently of the rest of the page), this was quickly deprecated. Use <div> to create this effect. To qualify as a layer to NN4, your div must be given the position style property, as well as the id attribute.
  • To get to any element on the page, you must first access the layer element that it is contained in, which itself is thought of as a nested document. This redundant extra layer of complexity is unnecessary in the other DOMs.

Let’s say we have to get to a paragraph that’s inside a div, which in turn is inside another div which is positioned absolutely on the page. The HTML looks like this:

<div id="header">

<div id="masthead"><p id="hello">Welcome</p></div>
</div>

The DOM call for that paragraph in Netscape is

window.document.header.document.masthead.document.hello

No, really. For every notional “layer” you need to put another document level to get access to anything below it. It’s a ridiculously complex method for something that is accomplished so easily in other browsers (document.getElementById('hello')). Oh, and remember how the window level can usually be safely left out of a DOM call unless you have created more than one window? Well, apparently that doesn’t apply to Navigator on the Mac, so you have to put it in.

The new model even disrupts some old Level 0 scripts, as an image contained in a div can no longer be referenced by just its name, it needs this silly document malarkey.

document.layers['divId'].document.images['imagename']

Through all the examples above I could have used document.layers['divId'] instead of document.divId, an option similar to one in the Level 0 DOM. Just trying to keep these Netscape code snippets as short as is possible (i.e. not very).

Code Branching

As you can imagine, the mere existence of three different methods of writing scripts poses something of a compatibility problem. Give a browser a DOM call that it doesn’t support and you’ll get a charming JavaScript error. So, we need a way to check which DOM the browser supports and then branch our code in three directions. For this we use an object detect. Yeah, it’d be great if this wasn’t necessary, but it is. For true browser compatibility, you’ll need to do this for each of your advanced scripts.

First we check for DHTML support of any sort, and then throw the relevant code to each type of browser:

if (document.getElementById || document.all || document.layers) {
  if (document.getElementById) {
      // Level 1 DOM code
   }
   else if (document.all) {
      // Microsoft DOM code
   }
   else if (document.layers) {
      // Netscape DOM code
   }
}

To spare your sanity, you can use a JavaScript library like » prototype or » jQuery to reference your elements. Using one of these strategies means you won’t have to write the code-branching yourself, which is handy. Best to place this function in an external included script file so all of your pages can use it.