Netscape Netcenter  Search  |  WebMail  |  My Netscape  |  Buddy Chat  |  Help  |  Download   

You are here: Home > Computing & Internet > Web Building > Studio > Feature Story
Feature Story
spacer gif Click here! Click here! Click here!
  Departments
  Web Building Studio
Designing
Scripting
Producing

Power Builder by CNET
Web Authoring
Web Programming
Web Graphics
Web Servers
Web Business

  Computing & Internet
  Software Store
Download
Hardware
Tech Resources
Tech News
Web Site Services
Software Reviews
Games
Support


JavaScript DHTML Utilities:
Dynamic HTML Without the Hassle

By Michael Bostock
Netscape Production Engineer
 

The utilities are divided up into three main components. The first is "behaviors." Behaviors define how layers interact with the user. For example, is the layer draggable? What happens when the user clicks on the layer, or puts her mouse over it? The second component is "motion." This lets you quickly and easily make moving elements - either transitions, or layers that fly across the page. Finally, the utilities let you dynamically load and play sounds without having to understand Netscape's LiveAudio. Together these three components can make it easy to develop compelling DHTML content.
Contents


How to Use the DHTML Utilities
Before you do anything, you need to understand layers. Whether you use the W3C standard Cascading Style Sheets or the depreciated <LAYER> tag, you can't have Dynamic HTML without the layers. To learn about Dynamic HTML, check out Netscape's Web Building Studio Web site for content developers.

Including The Library Files
The first step to using the utilities is to include them into your HTML document. Including the DHTML Utilities is a simple process; all you need to do is add the following code somewhere inside the head of the document (between the <HEAD> and </HEAD>):

View the code.

(Alternatively, you can download the files [behavior.js, motion.js, and sound.js] to your own hard drive by right-clicking on the links, choosing "Save Link As..." and then using the libraries locally.) Of course, if you only want to use part of the utilites (the Behavior Object, e.g.), you only have to include the .js file for that specific object (behavior.js).


The Behavior Object
The Behavior Object lets you provide interactivity to the elements on your Web page without having to worry about the JavaScript Event Model. Futhermore, it lets you create a behavior and easily apply it to multiple layers. A behavior is a collection of event-action pairs that can be applied to (associated with) a layer. Events are anything the user does to interact with the Web page, from clicking the mouse to pressing a key. The DHTML utilities let you assign actions (functions) for each of those events. Finally, because draggable layers are so commonly used, the Behavior Object has draggability built-in.

Creating A Behavior
To use the Behavior Object, you first have to create one. Use the Behavior's constructor function, like so:

myBehavior = new Behavior();

(Optionally, you can pass the constructor true as an argument, and the resulting Behavior Object that is created will be draggable.) After the Behavior has been created, it's up to you to define what it does. To do this, you use the setAction() function. The setAction() function takes two arguments. The first is the type of event you want to handle, and the second is what action you want to take place (the name of a function to be called on the event). Here are the different values that can be passed as the first argument to setAction():

Argument Plain English Equivalent
"MOUSEDOWN" The user puts the mouse down on the layer.
"MOUSEUP" The user releases the mouse on the layer.
"MOUSEMOVE" The mouse is moving over the layer.
"MOUSEOVER" The mouse enters the layer area.
"MOUSEOUT" The mouse leaves the layer area.
"CONTAINERPUSH" (See "Layers As Containers.")
"CONTAINERPULL" (See "Layers As Containers.")

N.B.: the "MOUSEMOVE" event is independent of whether the mouse button is pressed or not. "MOUSEOVER" and "MOUSEOUT" are generally used in combination to create "roll-over" effects. (If you've ever seen an image change when you put the mouse over it, you know what a roll-over effect is.)

A Simple Example
Here is an example of a useful behavior:

myBehavior = new Behavior();
myBehavior.setAction("MOUSEOVER", hilite);
myBehavior.setAction("MOUSEOUT", unhilite);
myBehavior.setAction("MOUSEUP", start);
myBehavior.applyBehavior(myLayer);

You could then define the roll-over functions like so:

function hilite() {
  if(this.background) this.background.src = "red.gif";
  else this.style.backgroundImage = "url(red.gif)";
}
function unhilite() {
  if(this.background) this.background.src = "blue.gif";
  else this.style.backgroundImage = "url(blue.gif)";
}

This would switch the background image of the layer to "red.gif" when the mouse goes over, and returns it to "blue.gif" when the mouse leaves. (If you want tools to help you set layer properties [CSSP] from JavaScript without understanding the differences between the two browsers' implementation, check out a cross-browser API that Netscape created.) When the user clicks on the layer, start() - or whatever function you want - would then perform some action (say, showing a layer or starting an animation). Here's that same example, in action:





Updating a Behavior
Once you've created a behavior, at some point you'll probably want to change attributes of that behavior, even after you've applied that behavior to a layer. Updating a behavior is as easy as defining it. To change an action associated with an event, simply use the
setAction() function; this will override whatever was set before. If you want to get rid of an action, pass null as the second argument of setAction(). Once the behavior has been changed, it will only take effect on whichever layers you call applyBehavior().

If you want to change a behavior's draggability, all you have to do is set the behavior's draggable attribute (for example: "myBehavior.draggable = true;").

One of the advantages of defining behaviors instead of hard-coding them yourself is the ability to make multiple layers behave in the same way. Once you've defined the Behavior Object, just call applyBehavior() for each layer you want to be associated with that behavior. Then, updating behaviors of layers becomes even easier. If you change a Behavior's attribute, you can update all the layers associated with that behavior. To do this, use the update() function. ("myBehavior.update();", e.g.) Of course, you can continue to use applyBehavior() if you only want to update a specific layer, and not all layers associated with the behavior.

Layers As Containers
Another useful feature of the Behavior Object is the ability to define containers for a layer. Here's an analogy to explain. Imagine one layer representing a Crayola crayon box, and another layer representing a Burnt Sienna crayon. It is frequently useful to know when the user removes the crayon from the box (when the user "pulls" the layer outside of the container layer) or puts the crayon in the box ("push"). To use the container functions, you first define different containers for the Behavior. (The Behavior can have multiple containers.) Do this using the
addContainer() function, with the only argument being the layer you want to function as a container. Next, you set an action for the Behavior, either "CONTAINERPUSH" or "CONTAINERPULL". Here's an example.

myBehavior = new Behavior(true);
myBehavior.addContainer(myLayer);
myBehavior.setAction("CONTAINERPUSH", hello);
myBehavior.setAction("CONTAINERPULL", goodbye);

Thus, when the user drags a layer with the behavior myBehavior onto the layer "container", hello() is called. If the user then drags the layer out of the container, goodbye() is called. These two functions are passed an argument which represents the container the layer was pushed on to or pulled from. (And "this" for those two functions refers to the layer being moved by the user.)

Here's a similar example in action:





You can also remove containers from the behavior, using the
removeContainer() function.

Additional Features
You can set certain restrictions on how a layer is draggable. Two attributes of the Behavior Object,
hLock and vLock, accept boolean values and determine if the layer can be moved horizontally and moved vertically, respectively. The default value is false. You can also specify a range that the layer can be dragged in (a bounding rectangle of which the layer cannot be dragged outside). To do this, use the function setBounds(), with the arguments being the left, right, top and bottom position of the bounding rectangle (in that order). The example above used setBounds() like so:

myBehavior.setBounds(0,500,0,64);

In addition to handling events for you, the DHTML utilities has three simple functions to tell if a modifier key (shift, alt, or control) was depressed on an event. These three functions are isShift(e), isAlt(e), and isControl(e). They return a boolean value. Pass them the same argument that is passed to the action associated with an event. (For instance, the hilite(), function above was passed the event but ignored it. To access the event, change the prototype to function hilite(e). You could then use isShift(e) to see if the shift key was down.)

For a first-hand experience of what the Behavior Object is capable of, check out this interactive demo.


The Motion Object
Aside from adding interactivity to layers, the other most common "cool thing" people want in DHTML is motion. Motion typically comes in two forms: transitions and movement. Transitions involve making a layer visible or invisible gradually. Movement means moving a layer from one position to another gradually. Unfortunately, the way to go about animating such motions is not always simple - especially if you want to do several motions in sequence. (JavaScript makes it much easier to do animations in parallel rather than in sequence.)

The Motion Object supports both transitions (in a variety of forms) and movement. It also provides an easy way to do multiple motions in sequence, or in parallel.

Creating A Motion Object
To use the Motion Object, you first have to create one. Use the Motion Object constructor, and 3 arguments:

myMotion = new Motion(direction, ex, length);

The first argument, direction, applies to what direction the motion is in. For movement, the value could be anyone of "H", "V" or "HV". Here "H" stands for horizontal, and "V" stands for vertical. For transitions, the value is "L", "R", "U", "D", or any combination or those letters. (They stand for left, right, up and down, respectively.) Since the Motion Object can be used for both transitions and movements, you can combine acceptable values for both transitions and movements. For instance, "HVLRUD" would build a Motion Object with motion in all directions.

The second argument, ex, is also a boolean value. It specifies whether the motions are exclusive. If ex is true, the motions happen in sequence. If false, the motions happen in parallel.

The final argument specifies the approximate time you want the motion to take in seconds. Partial seconds (2.34, e.g.) are acceptable.

Using the Motion Object: Transitions
Once you've built the Motion Object, to perform a transition on a layer, all you have to do is use the
applyTransition() function. Here's the syntax:

myMotion.applyTransition(layer, fadein);

The second argument, fadein, is a boolean. If true, it specifies a transition that brings a layer into visibility. If false, the layer will be "faded out." Optionally, you can specify the destination clipping coordinates of the layer by adding four more arguments (left, right, top, and bottom):

myMotion.applyTransition(layer, fadein,
                         clipLeft, clipRight,
                         clipTop, clipBottom);

Using the Motion Object: Movement
Similar to the
applyTransition(), there is an applyMovement() function to get a layer to move. The applyMovement() function takes three arguments, like so:

myMotion.applyMovement(layer, x, y);

Here layer is the layer getting moved, x is the destination x coordinate and y is the destination y coordinate of the layer's top-left corner.

Updating A Motion
After you've created a Motion Object, it's possible to change attributes of the Motion Object. This way you can still apply motions in sequence, but they don't have to be the same type of motions. To update a Motion Object's attributes, use the
changeAttribute() function. Here's the syntax:

myMotion.changeAttribute(attributeName, value);

The first argument, attributeName, refers to which attribute you want to change. It can be one of "direction", "ex" or "length". (See above to learn what these attributes mean.) The second argument is the value you want the attribute to have.

A Simple Example
In this example, a layer is faded in, moved across the screen, and then faded out. This is done in sequence.

myMotion = new Motion("HVLRUD", true, .75);
myMotion.applyTransition(myLayer, true);
myMotion.applyMovement(myLayer, 400, 0);
myMotion.applyTransition(myLayer, false);

See the result!





(Note: In cases where user events initiate a motion, it is best to only have one Motion Object controlling a layer at a time. One solution is to store the Motion Object as a global variable. If it is null, create a new Motion Object. Otherwise, use the existing object. This ensures that two [or more!] Motion Objects won't be conflicting for control of the layer, leading to unpredictable results.)

Additional Features
In addition to applying transitions and movements to layers, often times it would be useful to be able to evaluate a snippet of code in sequence. For instance, you may want to evaluate some code, but only after an animation sequence has completed. For this purpose, the JavaScript function
eval() has been built into the Motion Object. If the Motion Object is in exclusive (sequence) mode, that eval() will be evaluated in the sequence it was called. To see more of what the Motion Object can do first hand, check out this interactive demo.


The Sound Object
The final component of the JavaScript DHTML Utilites is the Sound Object. You can use the sound Object to simplify the loading and playing of sounds - and you don't have to understand Netscape's LiveAudio. Futhermore, since you can only play one sound at once, the Sound Object provides you with an easy way to play multiple sounds in order without worrying about it. (Note: because IE does not support LiveAudio, the Sound Object does not do anything under IE.)

Here's an example of using the Sound Object:

mySound = new Sound();
mySound.addSound("cid.wav", "cid");
mySound.load();
mySound.playSound("cid");

The first line calls the constructor argument to create a new Sound Object. Then, you associate sounds with the Sound Object using addSound(), with the first argument being the URL of the sound, and the second argument being the name you want to associate with the sound. After you've added as many sounds as you want, call load() to load all of these sounds. Then, you can call playSound() with the name of the sound you want to play. If you call playSound() multiple times, it will play those sounds in sequence (not cutting off whichever sound is currently playing). Also, it will wait until the sound is loaded before attempting to play it.

Here's an example. First, load the sounds. Then, listen to the world's shortest question. Note that if you click the previous link multiple times, it will play it as many times as you clicked the link, without interrupting the sound that is already playing.


Final Note
The DHTML Utilities aren't meant to be a be-all, end-all solution to interactivity and user functionality in DHTML Web pages. They are meant to make it easier make your Web pages dynamic, whether you already know JavaScript or not.

Since there's quite a bit you can do with the DHTML Utilities, I've provided a quick reference sheet. If you're developing DHTML with these utilities, print it out and keep it with you for quick access. There are also some extra goodies described in the reference sheet that haven't been mentioned here - you may find them useful.


About the Author
Michael Bostock is a class of 2000 student at Princeton University in New Jersey. He is a Computer Science major in the Engineering school. Over the summer, when he's not interning with Netscape Communications Corporation, he enjoys snow cones, water sports, and Papier-Mâché.


Check out these other Web Building sections:
Designing: Creativity, graphics, writing, layout, architecture
Scripting: Coding, programming, and authoring for web pages
Producing: Site and project managing, commerce, advertising
Help  |  Site Help Map  |  Advertise With Us  |  Add Site
  Netscape Channels
Autos
Business
Computing & Internet
Entertainment
Family
Games
Health
Lifestyles
Local
Netscape
Netscape Search Categories
News
Personal Finance
Real Estate
Research & Learn
Shopping
Small Business
Sports
Travel

Copyright © 2000 Netscape Communications
1