DHTML & netscape 6
You will probably have heard that Netscape 6 is coming, sometime. Not necessarily sometime soon, but sometime. The unkind suggest that the decision to name it Netscape 6 (the last major version was 4.7) was because it would not be released until Internet Explorer was on version 6. (The cynic in me would add “at least” to the end of that sentence.)
With Netscape 6 will come changes. It is going to be the most standards-compliant browser released by the two major vendors. The problems start because none of its predecessors were. Now, there are two routes that Netscape could have taken: one would introduce standards compliance while maintaining backward compatibility for old Netscape code; the other would introduce standards compliance and let old Netscape code fall over. Guess which course Netscape has taken?
The pros and cons of this are something to be talked about elsewhere, but the implications are stark. When Netscape 6 is released, no one knows how it will be taken up. Between a quarter and a third of Net users currently use Netscape, mainly one of the fourth-generation versions, but there is no way to tell if they will migrate in large numbers to version 6 or stick with what they know (and what works). If they do shift en bloc to version 6, they are going to find that some, possibly many, Web sites simply will not work.
In particular, sites which make use of JavaScript to manipulate “layers” will not work as they did in the version 4 browsers.
For those who have not come across “layers” before, these are basically two dimensional boxes of content which can be positioned absolutely on a page; they can overlap, and, using JavaScript, be moved around, hidden or revealed.
Layers were introduced with the Netscape-specific <layer> tag, but it was never adopted by Microsoft and is not an officially (i.e. W3C) recognised part of HTML. However, precisely the same functionality is available to browsers supporting CSS using CSS-positioning, particularly as applied to the <div> element. This works in both Netscape and Internet Explorer, so the Netscape-specific <layer> tag is rarely used. So, unless I specify otherwise, when I say “layer” here I mean “CSS-positioned <div>” — it’s a bit less cumbersome.
Netscape 6 presents no problem to simply having layers in a document. If you wish to lay out a page using several layers to set the position of your headers, content and navigation, that will work. The trouble starts when you want to do something dynamically to a layer using JavaScript.
Netscape 6 does not just stick to the W3C standards for HTML — so the <layer> tag, which is a Netscape-specific element, will not render in Netscape 6 — it also adheres to the recommendations for the DOM.
The DOM specifies how different objects in a Web document relate to each other, and determines how you can access them using scripting. Unfortunately, the recommended DOM is rather different from the way either Netscape or MSIE currently handle document objects.
Let’s look at this using the example of changing the visibility of a layer.
Internet Explorer
If you wished to, say, make a layer visible, you might produce some JavaScript like this for Internet Explorer:
function showTheLayers(objectStr) {
var theObj;
var changeStr;
if (document.all) {
changeStr = "document.all['" + objectStr + "']";
theObj = eval(changeStr);
if (theObj) {
theObj.style.visibility = "visible";
}
}
}
(This is quite simplified for clarity. In actual use you would want to be able to set the layer’s visibility to “hidden” as well as “visible”, and you would probably send to parameters to a function to determine which; but we will ignore all that so that we can concentrate on the way we actually handle the layer.) If the layer was <div id="layerID">, and note that the ID must be unique, the function would be called by something like:
<a href="javascript:showTheLayers('layerID')">show the layer</a>
After the variable declarations, the first line of the function checks if document.all is true — document.all being a part of the Internet Explorer document structure.
An aside: in general if you are checking for the existence of a specific browser, this is not the way to do it; but here we are checking for the presence of document.all because we want to use it.
Having confirmed the existence of document.all, the function takes the layer ID, which has been passed to it as an argument from the function call, and converts it to an object definition which can be used in the final command, which parses as:
document.all['layerID'].style.visibility = "visible"
In Internet Explorer 4 and above, that will reveal the hidden layer “layerID”. (If the layer is already visible, nothing will happen.)
Now you need to allow for Netscape 4 users.
Netscape 4
In the same format as before is the function as it would be written for Netscape 4:
function showTheLayers(objectStr) {
var theObj;
var changeStr;
if (document.layers) {
changeStr = "document.layers['" + objectStr + "']";
theObj = eval(changeStr);
if (theObj) {
theObj.visibility = "show";
}
}
}
Note that although the HTML element we want to manipulate is a div, document.layers is the way we access it in Netscape 4. Netscape regards CSS-positioned objects as though they were layer elements.
Parsing the final command this time, we get:
document.layers['layerID'].visibility = "show"
Note that instead of IE’s “visible” and “hidden” Netscape 4 uses “show” and “hide”.
In a real page the code for IE and Netscape would be combined in one function, with an if … else construct determining whether the document.all or document.layers code was executed. If the page were loaded in IE, the code would take the document.all fork, if in Netscape 4 the document.layers fork.
And in Netscape 6, it would do nothing.
Netscape 6
Netscape 6 does not support the <layer> tag, it does not support document.layers; it also does not support document.all. The W3C-recommended DOM is quite different from the Netscape and IE approaches, stemming from a very specific view of how Web documents should be built. As a result, any page written using JavaScript-manipulated layers, whether done by hand or using code generated by Dreamweaver, etc., will simply not work in Netscape 6.
One way to access objects in Netscape 6 is through the getElementById() method. Don’t go rushing off to look it up in your JavaScript book(s) — unless you have a very recent one — it won’t be there.
The comparable code to the above two examples for Netscape 6 would be:
function showTheLayers(objectStr) {
var theObj;
var changeStr;
if (document.getElementById) {
changeStr = "document.getElementById('" + objectStr + "')";
theObj = eval(changeStr);
if (theObj) {
theObj.style.visibility = "visible";
}
}
}
Here the final command parses as:
document.getElementById('layerID').style.visibility = "visible"
Note that round brackets are used — as you would expect with a method — not square, and that Netscape 6 discards “show” and “hide” for “visible” and “hidden”. The syntax is more like Internet Explorer’s than Netscape 4’s, but not identical.
For the foreseeable future, then, if we want to use such techniques we are in the delightful position of having to produce code with three forks: document.layers for Netscape 4, document.all for Internet Explorer, and document.getElementById for Netscape 6. (Of course there is always the approach of not using any of these, not relying on JavaScript, and creating pages which function in any browser… )
The following code example pulls together the three techniques for addressing layers and combines them with code to determine whether you want the layer made visible or hidden. It would be called using something like the following (remember that the layers you want to adjust must have unique IDs):
<a href="javascript:layerVisChange('layerID','state')>text</a>
The second argument, ‘state’, should be either ‘show’ or ‘hide’, and the code will handle the change to ‘visible’ or ‘hidden’ as necessary. So here is a JavaScript function which will show or hide layers in Netscape 4, Netscape 6, and Internet Explorer 4 & 5:
<script type="text/JavaScript">
function layerVisChange(objectStr,visStr) {
var changeStr;
var theObj;
if (document.all) {
if (visStr == "show") {
visStr = "visible";
} else if (visStr == "hide") {
visStr = "hidden";
}
changeStr = "document.all['" + objectStr + "']";
theObj = eval(changeStr);
if (theObj) {
theObj.style.visibility = visStr;
}
} else if (document.layers) {
changeStr = "document.layers['" + objectStr + "']";
theObj = eval(changeStr);
if (theObj) {
theObj.visibility = visStr;
}
} else if (document.getElementById) {
if (visStr == "show") {
visStr = "visible";
} else if (visStr == "hide") {
visStr = "hidden";
}
changeStr = "document.getElementById('" + objectStr + "')";
theObj = eval(changeStr);
if (theObj) {
theObj.style.visibility = visStr;
}
}
}
</script>
Further reading:
- W3C: Document Object Model (DOM)
http://www.w3.org/DOM/ - WDVL: The Document Object Model Dissected
http://www.wdvl.com/Authoring/DHTML/DOM/ - Webmonkey: Intro to the Document Object Model
http://hotwired.lycos.com/webmonkey/html/97/32/index1a.html
© DC 2000. All rights reserved.


