Cross Browser DHTML Development: An Example
K. Yue October 18, 2000
Copyright 2000
Introduction
One of the more difficult issues in dynamic HTML development is the different versions of DHTML support by the two major browsers: Netscape's Navigator and Microsoft's Internet Explorer. Their supports of Javascript are not identical. More importantly, their Document Object Models (DOM) are quite different.
In this article, we present a simple example of cross browser DHTML development by converting the famous Netscape-specific fish example to a cross browser version.
The Swimming Fish Example
The original swimming fish example appeared in the Netscape's DHTML guideline in the early days of DHTML. It shows a fish, three poles and a button. When the button is clicked, the fish swims across the poles forever.
The fish is an animated gif that moves its tail continuously to add liveliness. The example is simple. When the button is clicked, it increments the x location of the fish periodically. When the x location of the fish is greater than a certain value, it is reset to its starting location.
The source code of the original swimming fish (fish.html):
<HTML>
<HEAD>
<TITLE>Swimming Fish</TITLE>
</HEAD>
<BODY BGCOLOR="#ffffff">
<LAYER NAME="bluepole" LEFT=160 TOP=150>
<IMG SRC=bluepole.gif>
</LAYER>
<LAYER NAME="greenpole" LEFT=360 TOP=150>
<IMG SRC=greenpol.gif>
</LAYER>
<LAYER NAME="redpole" LEFT=260 TOP=150>
<IMG SRC=redpole.gif>
</LAYER>
<LAYER NAME="fish" LEFT=40 TOP=170 ABOVE="redpole">
<IMG SRC=fish1.gif >
</LAYER>
<SCRIPT>
<!-- Simple move function -->
function movefish() {
var fish = document.layers["fish"];
if (fish.left < 400) {
fish.offset(5, 0);
}
else {
fish.left = 10;
}
setTimeout("movefish()", 10);
return;
}
</SCRIPT>
<H1>Fish Example 1</H1>
<FORM>
<INPUT type=button value="Move the fish"
OnClick="movefish(); return false;">
</FORM>
<P>
(This demonstration requires Netscape Navigator 4.0
or later.)
</BODY>
</HTML>
Netscape uses the layer tag to create layers. Layers defined later have higher z-index values and layers with higher z-index values hide layers with lower z-index values inside the document. The attribute "above" is used to identify the layers that are above the current element. Hence, the z-index of the red-pole is the largest as it is 'above' that of the fish. The z-index of the fish is higher than that of the green-pole and blue-pole since it is defined later.
The movefish() function is the event handler for the click event of the "move the fish" button. The function updates the x location of the fish by checking and setting the left property and by calling the Netscape's function offset. It then calls itself after 10 mini-seconds.
Conversion to Support Both Browsers
To support multiple browsers, it is first necessary to identify the browser. There are many ways to do so. A simple method is to check for objects peculiar to the browsers. For example, Netscape has the built-in collection document.layers, but not document.all. IE is the other way around. Thus, the following code can be used to insert browser-specific code.
if (document.layers) {
// Netscape code
} else if (document.all) {
// IE code.
}
In cross browser dynamic HTML development, it is common to develop the program for one file and then convert the program to support multiple browsers. The process of conversion includes the conversion of
HTML Tag Conversion
In the fish example, <LAYER> is a tag used only by Netscape. However, it can be replaced by a <div> tag with a style attribute including using absolute positioning.
For example, the HTML tag for the blue-pole:
<LAYER NAME="bluepole" LEFT=160 TOP=150>
<IMG SRC=bluepole.gif>
</LAYER>
can be changed to:
<div style="position:absolute;top:150px;left:160px;z-index:1"
id="bluepole">
<img SRC=bluepole.gif>
</div>
There are several changes:
Since the attribute above is not supported in IE, the z-index is used to indicate which images are on top of the others. Thus, at 4, the z-index of the redpole is the largest.
<div style="position:absolute;top:150px;left:160px;z-index:1"
id="bluepole">
<img src=bluepole.gif>
</div>
<div style="position:absolute;top:150px;left:360px;z-index:2"
id="greenpole">
<img src=greenpol.gif>
</div>
<div style="position:absolute;top:150px;left:260px;z-index:4"
id="redpole">
<img src=redpole.gif>
</div>
<div style="position:absolute;top:170px;left:10px;z-index:3" id="fish">
<img src=fish1.gif >
</div>
There is no need for any other HTML tag conversion.
Javascript Code Conversion
Again, since the example is simple, the only necessary change is in the function movefish().
function movefish() {
if (document.layers) {
var fish = document.layers["fish"];
if (fish.left < 400) {
fish.left += 5;
}
else {
fish.left = 10;
}
}
else if (document.all) {
var fish = document.all["fish"];
if (fish.style.pixelLeft < 400) {
fish.style.pixelLeft +=
5;
}
else {
fish.style.pixelLeft =
10;
}
}
setTimeout("movefish()", 20);
return;
}
The Netscape-specific code is first moved into the then part of the Netscape-browser test (the document.layers test). In the IE-specific part (the document.all test), only minor changes from the Netscape's code are needed.
IE does not support document.layers. Instead, it has a built-in collection document.all, which includes one element for every HTML element in the document. An element with an id abc, such as <p id="abc"> can be referred to document.all["abc"]. For an element, IE supports the property "style," which contains the inline style properties of the element. Most of the mapping from CSS style property names are straightforward: any hyphens are removed and the first letters of any subsequent words are capitalized. For example, background-color in CSS becomes backgroundColor. Thus to change the background color of the element with id "abc" to yellow, the following statement can be used:
document.all["abc"].style.backgroundColor = "yellow"
Finally, we need to identify the right property for IE to set. Although IE supports a left property, it is not the same as the left property of Netscape. The left property of IE accepts a string representing "the position of the object relative to the left edge of the next positioned object in the document hierarchy." The correct IE property is pixelLeft, which represents the value of the Cascading Style Sheets (CSS) left attribute. Thus, to update the fish position in IE:
var fish = document.all["fish"];
if (fish.style.pixelLeft < 400) {
fish.style.pixelLeft += 5;
}
else {
fish.style.pixelLeft = 10;
}
The entire new program (newfish.html):
<HTML>
<HEAD>
<TITLE>Swimming Fish</TITLE>
</HEAD>
<BODY BGCOLOR="#ffffff">
<div style="position:absolute;top:150px;left:160px;z-index:1"
id="bluepole">
<img src=bluepole.gif>
</div>
<div style="position:absolute;top:150px;left:360px;z-index:2"
id="greenpole">
<img src=greenpol.gif>
</div>
<div style="position:absolute;top:150px;left:260px;z-index:4"
id="redpole">
<img src=redpole.gif>
</div>
<div style="position:absolute;top:170px;left:10px;z-index:3" id="fish">
<img src=fish1.gif >
</div>
<SCRIPT>
<!-- Simple move function -->
function movefish() {
if (document.layers) {
var fish = document.layers["fish"];
if (fish.left < 400) {
fish.left += 5;
}
else {
fish.left = 10;
}
}
else if (document.all) {
var fish = document.all["fish"];
if (fish.style.pixelLeft < 400) {
fish.style.pixelLeft +=
5;
}
else {
fish.style.pixelLeft =
10;
}
}
setTimeout("movefish()", 20);
return;
}
</SCRIPT>
<H1>Fish Example 1</H1>
<FORM>
<INPUT type=button value="Move the fish"
OnClick="movefish(); return false;">
</FORM>
<P>
</BODY>
</HTML>
Conclusion
Cross browser dynamic HTML development is tedious. This article presents an example to illustrate related issues.
Dr. Kwok-Bun Yue
Professor, Computer Science and Computer Information Systems
Chair, Division of Computing and Mathematics
University of Houston-Clear Lake
2700 Bay Area Boulevard
Houston, TX 77058
Yue's home page
yue@uhcl.edu
281-283-3864