Enterprise Software

Putting the dynamic in your DHTML

With Internet Explorer, you can attach behaviors to HTML elements, creating an object-oriented approach to page design. Phillip Perkins creates <DIV> objects contained in a bounding <DIV> that, when the user drags it, will continue on their directed courses within the bounding <DIV>.

Macromedia Flash allows developers and designers some freedom from the limitations of Web browsers as well as an interoperable solution. However, restricting yourself to Flash keeps you from experiencing some of the rich features of Web browsers.

For example, with Internet Explorer (IE), you can attach behaviors to HTML elements, creating an object-oriented approach to page design. In this example, I'll create <DIV> objects contained in a bounding <DIV> that, when the user drags it, will continue on their directed courses within the bounding <DIV>.

The key design aspect is the ability to attach behaviors to HTML elements. In IE, this is done through associated styles. The style property for attaching behaviors is "behavior." You can attach a behavior through a nested <STYLE> tag, like this:

DIV.object {
    behavior: url(Behavior.htc);

From this snippet, you can see that a behavior is a reference to an HTC (HTML Component) file. Now that we have the basis for objectifying these HTML elements, we can create behavior scripts for controlling them.

Listing A contains the code for creating the behavior for our contained <DIV>s. There's a lot of code within this one component. If you notice at the top of the script, there are special tags that tell the browser what types of exposed properties and methods the component contains, as well as to what events to attach this component. The events are the standard HTML events.

When the component initializes (during the onload event), it obtains a uniqueId, records its containing parent to a member variable, and sets default values used in proceeding calculations. If you step through the event handlers for this object, you'll see that when a user clicks on the object—element_onmousedown()—some variable initialization occurs. What should occur next is the user will drag the object to another location.

As the user drags the object across the screen—element_onmousemove()—the object's position is changed to match the movement of the cursor. Then, the user should release the mouse button to send the object on its way.

When the user either releases the mouse button—element_onmouseup()—or the cursor escapes the object's area—element_onmouseout()—the release point is recorded, the time from when the user clicked on the object to release is calculated, and the object is given its own perpetual motion. The slope of the movement from the starting click point to the ending release point is calculated. This slope becomes the object's new path motion. The speed of the user's drag is calculated by using the distance and travel time of the object under the user's command. This speed is then used to create the motion of the object. Finally, the reciprocal of the speed is used to create the time interval at which the object's position will be updated.

During the interval timeout event—moveMe()—the rise and run of the object is used to transform the slope of the direction into a calculated motion path. This is done by dividing the smaller direction change by the larger direction change. The result is that one of the direction changes will always be 1 while the other will be less than 1. With each timeout, the larger of the two direction changes will be incremented by one vector unit. This could be either -2 or 2 pixels. The other will be incremented by two times the lesser direction change (i.e., If the rise is 2 while the run is 1, then the rise will increment by 1 * vector and the run will increase by .5 * 2 units each time). If the smaller change increase passes the vector unit (-2 or 2), then the object's position is changed to match. The remainder of the smaller change is added to a trash variable. The vector unit is then subtracted with each position change of the lesser direction change.

If the new position of the object is outside of the bounding element, the vector is then changed to match whichever bounding side is outside. This "bounces" the object off the inner walls of the bounding element.

Listing B is the HTML page that hosts these components. The HTML page is nothing more than the containing <DIV> and a nested <DIV>, which is the component element. Within the JavaScript, there are some supporting objects and functions to help with the component calculations. One of the things to note is that there is an object stack—objStack—variable that is used to help manage calls to the moveMe() method on the component during interval timeouts.

Copy the code and paste it into your own files. Be sure to name your HTC file "component.htc" as specified in the behavior style property. Run this example in IE 5.0 or above and watch your objects come to life.

Keep your developer skills sharp by automatically signing up for TechRepublic's free Web Development Zone newsletter, delivered each Tuesday.

Editor's Picks