Articles | What Is So Dynamic About Dynamic HTML
| back
Attention Mac Users:
Since DHTML and the DOM are still in the infancy of
development, some of the examples in this article may crash your system if you
are using MSIE4.0+.
We did our best to ensure the code was as user-friendly
as possible, but there are still some incompatibility problems between what the
browsers should do, and what they actually do.
Introduction
Dynamic HTML, or DHTML, is not something that can
easily be pointed out, or separated from other technologies. It is a group of
technologies, when brought together, enable a Web developer to bring a Web page
to life.
The three main technologies that make up DHTML are
HTML, JavaScript and Cascading Style Sheets (CSS). HTML is used for the basic
structure of the document, JavaScript to manipulate the Document Object Model
(DOM), and CSS to define the presentation and style of the document.
Before version 4 browsers, it could be argued that we
already had some form of DHTML with image swapping in NN3. MSIE3 supported the
first version of JavaScript (i.e., JavaScript first appeared in NN2), so neither
of these two browsers had support for the JavaScript Image object.
This isn't to say that these two browsers couldn't
display images -- they could, but those images couldn't be manipulated. To
enable images to be manipulated required two basic changes to the browsers -- a
change to the DOM to add an Image object to the document structure, and the
inclusion of this object within the JavaScript language.
However, the last part is not entirely true. Once an
object is available in the document or window, no extra JavaScript code is
required to support it. As long as the object has its own methods and
properties, it can be used, manipulated, and examined using the existing
JavaScript functionality.
MSIE4 is currently ahead of NN4 in its richness in the
DOM. By using the the document.all object array with MSIE4, it is
possible to address almost any object in a document, including images and text.
Sadly, this is not the case with NN4; let's hope this is addressed in later
releases of Navigator.
So what is so good about the DOM and objects? Both
Microsoft and Netscape are responding to the call from Web developers for the
need to be able to control more of the contents in a Web page. Until now, we've
only really been able to manipulate images using the Image object, and forms
using the Form object. In MSIE4, Microsoft created a whole new means of
accessing all the items within a document, oddly enough by introducing an all
encompassing object called all. Using the all object, it is
possible to access any discrete item within a document -- right down to a single
HTML tag. It is possible to access items using the identifier ID that can be
optionally given to any HTML tag, for example:
<P ID="myText">This is my text<\/P>
|
It is then possible to access the properties of the
text using the notation:
document.all('myText').propertyName
|
For example its possible to find out the actual text
using:
var text = document.all('myText').innerText
|
It is also possible to access items using the index
position, the following example highlights the first paragraph of a particular
document:
for (var i=0; i<document.all.length; i++) {
if (document.all(i).tagName == 'P') {
alert(document.all(i).innerText);
break;
}
}
|
One basic addition to the version 4 browsers was the
ability to layer information. In DHTML-ese, layering is more commonly
referred to as positioning. Layers are used to hold different documents,
which can then be positioned either relative to other content or
positioned absolutely on the page. The layers can also be positioned
above one another using z-order, as opposed to the x and y
coordinates. This means layers can overlap each other (e.g., to place text over
a graphic).
The only problem with positioning is that Microsoft and
Netscape have different implementations. NN4 uses the <LAYER><\/LAYER>
and <ILAYER><\/ILAYER> tags, while MSIE4 uses <DIV><\/DIV>
and <SPAN><\/SPAN> tags.
The downside of using LAYER and ILAYER
is that they do not appear in the HTML 4.0 specification, while DIV and
SPAN do. This doesn't mean you should stop using LAYER and ILAYER
-- there are some things that can't be done with DIV and SPAN
in NN4. This just means the DOM is more flexible in MSIE4 because DIV
and SPAN have been accepted as a standard.
This article will attempt to discuss how to change the
content of a document once the document has been displayed on the browser --
something that couldn't be done previously without reloading the document.
We'll show how to replace text, replace images, and
replace HTML.
Positioning with DIV, SPAN, LAYER, and ILAYER
The DIV and SPAN tags are grouping
elements that are "generic language/style container[s]." You can
combine DIV or SPAN elements along with a CLASS or ID
attribute to structure and style text in a document differently than the
surrounding text. For example:
<STYLE TYPE="text/css">
<!--
#myDiv {font-family: sans-serif; color: red;}
-->
<\/STYLE>
<P>This is normal paragraph text,
<DIV ID="myDiv">this isn't<\/DIV>
but this is.
<\/P>
|
Click
here to see how the above code is rendered in a CSS-enabled browser....
This is one important use of CSS combined with ID
attributes of DIV elements. As you can see there is usually a line
break before and after the DIV elements. The SPAN elements
avoid this:
<STYLE TYPE="text/css">
<!--
#mySpan {font-family: sans-serif; color: red;}
-->
<\/STYLE>
<P>This is normal paragraph text,
<SPAN ID="mySpan">this isn't<\/SPAN>
but this is.
<\/P>
|
Which
renders as...
The LAYER and ILAYER elements
(supported only in NN4), are used to position content in the browser, either in
the horizontal, vertical, or by z-order (i.e., the stacking order). Layers can
be positioned relative to the surrounding text or absolute to the top of the
container of the layer. Note that layers can also contain sublayers. The
document contains the top-most layers, therefore the document is the container
in these instances.
They can also be used similarly to DIV and SPAN
elements to structure and style the document text.
By default LAYER elements are rendered
relative to the surrounding text, but they don't reserve any space in the
container. For example:
<STYLE TYPE="text/css">
<!--
#myLayer {font-family: sans-serif; color: red;}
-->
<\/STYLE>
<P>This is normal paragraph text,
<LAYER ID="myLayer">this isn't<\/LAYER>
but this is.
<\/P>
|
Which
renders as...
The text "this isn't" is overlaid with
the text "but this is," because the layer, myLayer, is
another document. The text "this isn't" does not appear in the
container document (i.e., the document the paragraph resides in). (Note if you
are not using NN4 you'll not see the effect described here.) This is a different
approach than that taken by the DIV and SPAN elements.
This is where the ILAYER elements come into
use (ILAYER stands for "Inline Layer"). ILAYER
elements reserve room in the container document for the initial contents of the
layer:
<STYLE TYPE="text/css">
<!--
#myIlayer {font-family: sans-serif; color: red;}
-->
<\/STYLE>
<P>This is normal paragraph text,
<ILAYER ID="myIlayer">this isn't,<\/ILAYER>
but this is.
<\/P>
|
Which
renders as...
The three elements -- DIV, SPAN, and LAYER
-- can all break out from the current relative position and float free from the
container document. To do this we use the STYLE attribute to position
the layer absolutely:
<... STYLE="position: absolute;" ...>
|
For example:
<STYLE TYPE="text/css">
<!--
#myDivAbs {font-family: sans-serif; color: red;}
-->
<\/STYLE>
<P>
This is normal paragraph text,
<DIV ID="myDivAbs" STYLE="position: absolute;">this isn't<\/DIV>
but this is.
<\/P>
|
Which
renders as...
Note that the contents of the DIV elements no
longer reserve the space within the container document. The text is still
positioned relative to the preceeding text, as we have not yet specified the
absolute location of the layer. This again can be done using the STYLE
attribute, but it is outside the scope of this article. (Positioning and DHTML
will be covered in a future article.)
The notation within the STYLE attribute uses
the slightly different CSS notation, which require a colon (:) instead
of an equal sign (=), and a semi-colon (;) instead of a comma
(,) separator.
In an attempt to make the examples as generic as
possible, we'll use the DIV and SPAN elements wherever
possible. Where necessary, we will show how to use the LAYER elements
to support on NN4 what cannot be done using just DIV or SPAN
elements.
Detecting the Browser
Identifying whether the current browser has support for
DHTML is extremely important. We wouldn't want visitors on our sites to be put
off with a lot of error messages simply because they are using an older browser.
This was a common problem with image swapping scripts.
A badly written script wouldn't test to see if the
browser would support image swapping, a poorly written script would check to see
if the browser being used was NN3 and if so, it allowed the images to be
swapped. If the script didn't detect NN3 as the browser, it wouldn't allow the
images to be swapped. The problem with this approach is if the browser being
used is NN4 or NN5, or another browser with Image object support. A well-written
script actually detects support for the Image object directly. The following
test is all that's required:
<SCRIPT LANGUAGE="JavaScript">
<!--
if (document.images) {
// supports the image object
}
else {
// does not support the image object
}
//-->
</SCRIPT>
|
This technique can be carried over to version 4
browsers to detect for two new objects: document.all and document.layers.
MSIE4 supports the document.all object and NN4 supports the document.layers
object. Therefore, the following script will detect version 4 browsers:
<SCRIPT LANGUAGE="JavaScript">
<!--
if (document.all || document.layers) {
// version 4 or greater browser
}
else {
// not a version 4 or greater browser
}
//-->
</SCRIPT>
|
It will be necessary to detect MSIE4 from NN4 as well.
Therefore, the following script is sometimes more suitable:
<SCRIPT LANGUAGE="JavaScript">
<!--
if (document.all) {
// MSIE4+
}
else if (document.layers) {
// NN4+
}
else {
// not a version 4 or greater browser
}
//-->
</SCRIPT>
|
DHTML-related JavaScript Events
The following JavaScript events can be triggered by DIV
(D), SPAN (S), or LAYER (L) elements:
| |
STYLE="..." |
| |
|
position:relative; |
position:absolute; |
| Event: |
MSIE4 |
NN4 |
MSIE4 |
NN4 |
MSIE4 |
NN4 |
| onMouseOver |
D S |
L |
D S |
L |
D S |
L |
| onMouseOut |
D S |
L |
D S |
L |
D S |
L |
| onLoad |
|
L |
|
L |
|
L |
| onFocus |
|
L |
|
L |
|
|
| onBlur |
|
L |
|
L |
|
|
| onClick |
D S |
|
D S |
|
D S |
|
| onDblClick |
D S |
|
D S |
|
D S |
|
| onMouseDown |
D S |
|
D S |
|
D S |
|
| onMouseUp |
D S |
|
D S |
|
D S |
|
| onKeyPress |
|
|
|
|
D S |
|
| onKeyDown |
|
|
|
|
D S |
|
| onKeyUp |
|
|
|
|
D S |
|
Note: The events
triggered are dependent on whether the elements have a STYLE attribute
set to position:absolute; or position:relative;. The only two
events that are compatible with both browsers are onMouseOver and onMouseOut.
However, this shouldn't stop you from using event handlers from other objects
(such as forms and links) on the page from affecting the contents of a layer.
Also notice that the ILAYER elements do not
trigger any events.
Altering Content in Internet Explorer 4.0
Due to the richness of the DOM in MSIE4 it is sometimes
far easier to alter the content of a document than it is in NN4. For example, to
change the color of a layer is simplicity itself in MSIE4:
<P>
<DIV onMouseOver="this.style.color='red'"
onMouseOut="this.style.color='black'">
Move the mouse pointer over this text</DIV>
</P>
|
Which
in MSIE4 has the following effect....
Whereas in NN4 using a LAYER tag:
<P>
<LAYER onMouseOver="this.style.color='red'"
onMouseOut="this.style.color='black'">
Move the mouse pointer over this text</LAYER>
</P>
|
Which if included in this document would cause the
following error in NN4:
this.style has no properties.
|
This is because there are no style properties for
layers in NN4. Once the text has been rendered in the document it's not easy to
amend it.
For example, in MSIE4 to change the text in a layer:
<P>
<DIV onMouseOver="this.innerText='Ha! You moved the mouse over the text'"
onMouseOut="this.innerText='Move the mouse pointer over this text'">
Move the mouse pointer over this text</DIV>
</P>
|
Which
in MSIE4 has the following effect....
Again in MSIE4 its easy to change the HTML contained in
a layer:
<P>
<DIV onMouseOver="this.innerHTML='Lets be <FONT SIZE=+2>big</FONT>
and <B>bold</B>'"
onMouseOut="this.innerText='Move the mouse pointer over this text'">
Move the mouse pointer over this text</DIV>
</P>
|
Which
in MSIE4 has the following effect....
Note how the rest of the document shifts downwards to
accommodate the extra space required for the larger text.
Altering Content in Netscape 4.0
Because NN4 does not support the innerText, outerText,
innerHTML, and outerHTML properties, it is slightly harder to
alter the value of text or HTML. It is possible to alter the content LAYER
elements in NN4 by using the documents' write() method.
You may be aware that by using the document.open(),
document.write(), and document.close() methods, it is possible
to alter the content of another frame or window. Well, since a layer is another
document within the current document it is possible to use these three methods
to alter the content of the layer:
<SCRIPT LANGUAGE="JavaScript">
<!--
function over2() {
var text = '<FONT COLOR="red">Ha! You moved the
mouse over the text<\/FONT>';
document.layers['myLayer2'].document.open();
document.layers['myLayer2'].document.write(text);
document.layers['myLayer2'].document.close();
}
function out2() {
var text = 'Move the mouse pointer over this text';
document.layers['myLayer2'].document.open();
document.layers['myLayer2'].document.write(text);
document.layers['myLayer2'].document.close();
}
//-->
</SCRIPT>
<LAYER ID="myLayer2" onMouseOver="over2()" onMouseOut="out2()">
Move the mouse pointer over this text
</LAYER>
|
Which
in NN4 has the following effect....
Altering Content for both Internet Explorer and
Netscape 4.0
Using all the techniques discussed so far, let's
combine the solutions for MSIE4 and NN4 to create a solution that will work for
both MSIE4 and NN4, and at the same time fail safely in older browsers:
<P>
<SCRIPT LANGUAGE="JavaScript">
<!--
function changeContent(what,text) {
if (document.all)
what.innerHTML = text;
else if (document.layers) {
what.document.open();
what.document.write(text);
what.document.close();
}
}
//-->
</SCRIPT>
<P>
<DIV onMouseOver="changeContent(this,'<FONT COLOR=red>Ha!
You moved the mouse over the text</FONT>')"
onMouseOut="changeContent(this,'Move the mouse pointer over this text')">
<LAYER onMouseOver="changeContent(this,'<FONT COLOR=red>Ha!
You moved the mouse over the text</FONT>')"
onMouseOut="changeContent(this,'Move the mouse pointer over this text')">
Move the mouse pointer over this text
</LAYER>
</DIV>
</P>
|
Which
in MSIE4 or NN4 has the following effect....
This works because in MSIE4 the onMouseOver
and onMouseOut event handlers within the DIV elements pass a
reference to the changeContent() function to the DIV elements.
The innnerHTML property of the DIV elements are then changed
using the text value passed to the changeContent() function.
In NN4, the onMouseOver and onMouseOut
event handlers in the layer elements pass a reference to the changeContent()
function to the layer elements. The contents of the layer elements are changed
by opening and writing to the layer directly.
What Next?
Well, you don't have to restrict yourself to plain text
or HTML; you can include and manipulate images within layers as well. You can
also include links within the layers and then make use of other event handlers.
For example, the onMouseOver, onMouseOut, and onClick
event handlers can be used for the links themselves.
To illustrate this, the following example demonstrates
text link rollovers as opposed to image link rollovers -- the result is a lot
quicker than images:
<SCRIPT LANGUAGE="JavaScript">
<!--
function nnRoll(what,href,linktext,color) {
if (document.layers) {
var text = '<A HREF="' + href + '">' +
'<FONT COLOR="' + color + '">' +
linktext + '<\/FONT><\/A>'
what.document.open();
what.document.write(text);
what.document.close();
}
}
function msieRoll(what,color) {
if (document.all)
what.style.color=color;
}
//-->
</SCRIPT>
<P>
<LAYER onMouseOver="nnRoll(this,'http://www.yahoo.com/','Yahoo!','green')"
onMouseOut="nnRoll(this,'http://www.yahoo.com/','Yahoo!','blue')">
<A onMouseOver="msieRoll(this,'green')" onMouseOut="msieRoll(this,'blue')"
HREF='http://www.yahoo.com/'>Yahoo!</A>
</LAYER>
<BR>
<LAYER
onMouseOver="nnRoll(this,'http://www.netscape.com/','Netscape','green')"
onMouseOut="nnRoll(this,'http://www.netscape.com/','Netscape','blue')">
<A onMouseOver="msieRoll(this,'green')" onMouseOut="msieRoll(this,'blue')"
HREF='http://www.netscape.com/'>Netscape</A>
</LAYER>
<BR>
<LAYER
onMouseOver="nnRoll(this,'http://www.microsoft.com/','Microsoft','green')"
onMouseOut="nnRoll(this,'http://www.microsoft.com/','Microsoft','blue')">
<A onMouseOver="msieRoll(this,'green')" onMouseOut="msieRoll(this,'blue')"
HREF='http://www.microsoft.com/'>Microsoft</A>
</LAYER>
|
Which
in MSIE4 or NN4 has the following effect....
This works perfectly in MSIE4 and NN4 and fails safely
on older browsers. Note: The LAYER elements do not reserve any
space on the page. Break tags (<BR>) are used to keep the links
from overlapping each other in NN4. I have yet to work out a generic solution
that enables the layers to be positioned side by side across the page. It's
possible to insert extra ILAYER tags with a copy of the link text with
a style that hides the ILAYER, but on MSIE4 this shows up as extra text
between the links.
Conclusion
We have covered changing text and HTML, and altering
the style properties of text in a document dynamically. It is also possible to
add movement to a document (i.e., moving text and images around the screen using
Positioning). But again, this will be covered in a future article.
DHTML is not yet stable enough to use in mission
critical Web pages -- if you have a site that must work on all browsers then try
to avoid using DHTML. However, if you have the freedom to experiment, then do
so. But first, make sure you test your creations on as many platforms as
possible -- in particular NN4 and MSIE4 for Win95 and Mac. You may be surprised
to find that your carefully handcrafted DHTML may work perfectly on one browser,
then fail abysmally on another. But don't despair. Keep at it, and keep your
fingers crossed that future versions of the DOM will be more universal.
Articles | What Is So Dynamic About Dynamic HTML
|
back
|