This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.


MIND


This article assumes you're familiar with Dynamic HTML
Download the code (59KB)

Cutting Edge

Scripting Evolves to a More Powerful Technology--HTML Behaviors in Depth

Dino Esposito

HTML Behaviors, a new feature of Microsoft Internet Explorer 5.0, give you unprecedented power over the actions of your Web pages with Dynamic HTML.
A year and a half ago, I recommended that my customers consider Microsoft® Internet Explorer 4.0 when designing or upgrading their intranet systems. I told them that the most valuable benefit they could get from Internet Explorer 4.0 was Dynamic HTML (DHTML). A few months later, after looking at this advice in the context of some real-world projects, I realized that while DHTML is a fundamental technology, it is not always suitable for direct use by Web developers. DHTML scriptlets were a great step forward, but they only partially addressed DHTML's real problem. As I discussed in the November 1998 installment of Cutting Edge, the evolution of scripting is moving toward a more powerful technology: HTML behaviors.

    I'll start by discussing the structural limits of DHTML as a user technology and show you the behaviors of Internet Explorer 5.0 in action. I'll also take a strategic look at some of the newest innovations in Internet Explorer 5.0. To get an idea of what's new with Internet Explorer 5.0 (the browser software planned for inclusion in Office 2000 and Windows® 2000), read the article, "Internet Explorer 5.0: The Inside Story," in the September 1998 issue of MIND. Keep in mind that article was based on the first beta of Internet Explorer 5.0. With later pre-releases, some significant changes have occurred.

DHTML as a System Service

    A common but somewhat natural misconception that has overshadowed DHTML is that it's a technology geared toward users. In other words, while you can employ raw DHTML to write and enrich your final Web pages, you shouldn't for the following reasons:

  • It weighs down and overwhelms your pages with countless lines of script code.
  • It makes maintenance and readability more difficult.
  • It's a low-level API that shouldn't be used in today's sophisticated pages.
As you can see, there's a relationship among these three points. Namely, all lead you to conclude that using DHTML can be cumbersome. On the other hand, today you're used to seeing more articulated pages with complex functionality built in. In a certain sense, DHTML is the Web counterpart of the C language for Win32®-based applications. Nothing prevents you from writing a large desktop program in straight C, but it requires additional (and probably unnecessary) work to cut, paste, and arrange all the boilerplate code.

    When used in large and complex applications, DHTML is more useful as a basic system service than a client-side user technology for Web applications. In other words, use DHTML as the building blocks of the client tier, but don't put straight DHTML code in the actual HTML pages.

    For serious HTML development, more usable and powerful tools are needed to complement DHTML. While DHTML scriptlets have been a useful intermediate step in the evolution of scripting, an excellent solution to this issue is the new Internet Explorer 5.0 behaviors feature.

Behaviors are the Core

    To create DHTML pages that can survive a real-world project, you need a means to create reusable components to plug into pages and, even more importantly, a machinery to extend and filter the standard behavior of existing elements without replacing them with completely new ones. Being forced to substitute elements that you want to extend is not flexible, and isn't a better solution than having straight DHTML code.

    Over the past year, Microsoft has provided an incremental approach to solving this problem. They introduced scriptlets in Internet Explorer 4.0, and then behaviors with Internet Explorer 5.0. Keep in mind that there was no support for behaviors and their derivatives before Internet Explorer 5.0. So, there aren't any backward compatibility issues. In fact, behaviors are implemented as a Cascading Style Sheet (CSS) style, so they simply get ignored by older browsers.

    By supporting DHTML, the browser gives life to each element in the page—from anchors to images, and from single characters to a table row. HTML tags are given their own set of properties, methods, and events and can be programmed via scripts. DHTML scriptlets give you shortcuts to combine more elements and have them cooperate to expose a new programming interface and a new behavior.

    In my October 1998 column, I presented a scriptlet that was an advanced version of <TABLE>. It was capable of linking to a remote data source, downloading recordsets, and then adding rows and columns dynamically to fit the fields and the records found. All of this can be done with a few lines in an HTML page.

    However, there's a hidden catch to DHTML scriptlets: they always force you to replace existing components. For example, suppose you want to show off your intranet application with the now must-have hot tracking feature that makes a hyperlink text change color when the mouse hovers over it. From a logical point of view, it is just a slightly different version of the <A> tag. The <A> tag differs from normal HTML text because it holds a target URL, employs a different color and text style, and changes the cursor shape. The hot tracking version of <A> differs from the ordinary <A> by virtue of an additional feature: it changes color as the mouse enters and exits its area. Aside from the target URL, it's not difficult to imagine all the <A> characteristics described through a single CSS class.

    Is a comparison between HTML tags and Win32 windows reasonable? The Microsoft engineers who planned behaviors thought so. In Win32 programming, windows are essentially objects that expose a number of properties like icons, background color, UI style, title, mouse shape, and so on. A window always belongs to a class.

    A Win32-based application is made up of control windows, just like an HTML application is comprised of tags. What the window does throughout its life is coded in a function called the window procedure. This function is a primary attribute, and each window has one. The window procedure defines the window's behavior, and you can customize a window by changing or replacing its procedure. This is known as window subclassing, a fundamental part of the overall architecture of Windows. This principle can apply to HTML as well as shown in Figure 1.

Figure 1: Comparing HTML and Win32
Figure 1: Comparing HTML and Win32

    To add the hot tracking feature to anchors, you need to process a couple of mouse events, as shown in Figure 2. This code works fine with Internet Explorer 4.0, too. The hot tracking anchor element works exactly like an ordinary anchor, plus it handles two mouse events. It sports a slightly changed behavior, just like a subclassed window! A behavior is a new CSS style that refers to a URL. This URL is normally a Windows Script Component .wsc file or a new kind of HTML component called an HTC (more on this later). Here the author defines the script code that he wants to add to elements that include the style. The behavior is much like the window procedure that subclasses an existing window.

    Now I'll turn my attention to a couple of sample behaviors, demonstrating how they fill some of the gaps in DHTML and DHTML scriptlets. Then I'll examine the role of behaviors within the global architecture of Internet Explorer 5.0. Through the various prereleases, Internet Explorer 5.0 has shown itself to be a complete development platform for client-side programming.

    If you feel a bit uncomfortable with the plethora of names (DHTML scriptlets, Windows Script Components, HTC, and so on), take a look at the glossary in Figure 3.

Behaviors Like Windows Subclassing

    I'm going to adapt one of the first DHTML scriptlets I wrote, the HotImage scriptlet from the January 1998 installment of Cutting Edge. Basically, HotImage is a component that changes the source image when the mouse passes over it, usually switching from monochrome to color. If you write a bit of surrounding code, this component can become a cool replacement for buttons.

    Unfortunately, HotImage suffers from two major problems. First, you normally think of bitmapped buttons as having irregularly shaped buttons, so you want your bitmap to have a transparent background to fit seamlessly into the existing context. DHTML scriptlets are overlapping pages with their own background and other settings that are hosted by the main page, and these page settings might be in conflict at times. For instance, it's impossible to have a DHTML scriptlet fit smoothly on textured page backgrounds. The scriptlet has its own rectangular opaque area that covers the hosting page.

    Second, if you want to specify alternate text for your image, you have to expose a specific property that maps to the embedded <IMG> tag's alt attribute. Generally, this means that with scriptlets you can easily assemble and glue together multiple HTML objects to create a completely new programming interface. But when it comes to the simpler task of adapting the behavior of a single HTML tag, scriptlets can create trouble. Sometimes you really need new and complex objects, and under these circumstances DHTML is still a valid choice. More often, though, you need to change existing tags only slightly. Think of how you'd do it with Win32. If you want a hot tracking button you can resort to subclassing; you don't design a completely new common control.

The HotImage Behavior

    Figure 4 shows a test page demonstrating the HotImage behavior. Rather than having the user interface of two DHTML scriptlets, the images are two far simpler <IMG> tags within a two-column table:
<table border="0">
   <tr>
     <td><img class="hotimage" 
              src="mind1.gif"
              hot="mind2.gif"></img></td>
     <td><img class="hotimage" 
              src="msj1.gif" 
              hot="msj2.gif"></img></td>
   </tr>
 </table>
The full source code for the test page can be found in Figure 5. As you can see, there's no scripting code throughout the page to take care of the hot tracking process and switching the displayed image. The only odd things are the hot attribute and the CSS class name for both the elements.
Figure 4: HotImage Test Page
Figure 4: HotImage Test Page

    This hot attribute is more than just a custom tag attribute. To understand this, let's start with the CSS class assigned to the <IMG> tags. The hotimage class is defined like this:
.HotImage {  behavior:url(hotimage.wsc);}
The keyword behavior is a CSS style, and url(hotimage.wsc) is its content. The content is actually a URL. This means that the behavior of all the HTML elements that boast this style is filtered by the script lines inside the .wsc file. The .wsc file doesn't replace the predefined behavior of the tag, it extends it. In other words, an <IMG> will continue behaving like an <IMG>. Nevertheless, because of this style you can extend and filter mouse events and read and set attributes like any window procedure would do with windows. Figure 6 shows the implementation of the behavior.

    So now you've given a different behavior to the <IMG> tag, transforming it in a more specialized tag, but you've put no additional script code in the page. This is certainly much more readable than any other solution devised so far. The behavior is isolated in a precise and separate module that you can attach to any other <IMG> tag in any other page. To my ears, this sounds very reusable.

Passing Parameters to Behaviors

    One way to implement behavior is through Windows Script Components. For a primer on Windows Script Components you can look at my article, "Writing COM Objects with Scripting Languages," which appeared in the November/December 1998 issue of MSDN™ News (available at http://msdn.microsoft.com/developer/default.htm).

    To Internet Explorer 5.0, a Windows Script Component looks like a COM object implementing a certain number of interfaces—which set of interface depends upon the keyword that is assigned the type attribute:

<implements id="HotImageBehavior" type="Behavior" default/>
The type attribute of <IMPLEMENTS> is a kind of shorthand name to a functionality implemented by a number of COM interfaces: automation, event handling, and behaviors. See the sidebar "How Behaviors Work Under the Hood" to learn more about the underpinnings of Internet Explorer 5.0 behaviors.

    In the case of behaviors, the involved COM interfaces accomplish a main task: they attach the script code specified next to the context of the HTML element with that style. In Figure 6, the following lines

attachEvent("onmouseover", event_onmouseover);
 attachEvent("onmouseout",  event_onmouseout);
establish a link between the behavior code and the hosting page. The indicated procedures end up handling the specified mouse events. To continue the Win32 comparison, this resembles the way you switch among case branches in a typical message-based window procedure. The attachEvent function is a new method of the window object, which in turn is part of the Internet Explorer 5.0 DHTML object model.

    What if you need to pass information from the hosting page to the behavior's code? Notice that the code in Figure 6 also contains these lines:

<public>
 <property name="hot"/>
 </public>
This means that the component is also exposing an Automation interface with get and set properties. In the previous example, there was just one property called hot. This property characterizes the behavior and can be manipulated by the host page as if it were an attribute of the tag.

    Both of the following declarations are correct:

<img src="mind1.gif"
      hot="mind2.gif"></img>
 
 <img class="hotimage" 
      src="mind1.gif"
      hot="mind2.gif"></img>
The former—which is not of class hotimage—just exposes an attribute called hot with that content. In the latter, the hot attribute coincides with the get property defined by the Windows Script Component in Figure 6. This is an example of how you can pass information to the behavior. In the previous example, the hot attribute informs the behavior of the image required to display the hot state.

    Of course, a behavior can expose methods as well. For example, the following code snippet causes the <IMG> to expose an Enable method to turn hot tracking on and off:

<public>   <property name="hot"/>
 <method name="Enable">
      <parameter name="bEnabled"/>
    </method>
 </public>
Overall, behaviors let you extend the programming interface (namely, the object model) of any HTML tag with new properties, methods, and events (see Figure 7). In this month's source code you'll find a HotImage2 behavior that contributes to a functionality like the one described previously (see Figure 8). Notice that hot tracking is disabled when the mouse hovers over the image. The behavior can even define custom events for existing tags or handle standard events automatically.
Figure 7: Extending HTML with Behaviors
Figure 7: Extending HTML with Behaviors

    With the following code, you can enable the behavior to fire an onImageClick event:
<implements id="Behavior" type="Behavior" default>
    <event name="onImageClick" />
 </implements>
Such events can be raised when necessary, like when you click on the <IMG>.
attachEvent("onclick", event_onclick)
 •••
 function event_onclick() {
   oEvent = createEventObject();   
   // fill oEvent with info if necessary
   fireEvent("onImageClick", oEvent);
 }
Now you have a bitmap working as a button with all the necessary script code kept outside the main page. More importantly, the code is ready to be reused.
Figure 8: Testing HotImage2
Figure 8: Testing HotImage2

Behaviors Versus DHTML Scriptlets

    DHTML scriptlets were the first attempt to create HTML components. Although they have some drawbacks, you don't always have to dump them in favor of behaviors. Undoubtedly, behaviors are more powerful and flexible objects, but they aren't perfect for all possible uses.

    There are at least two circumstances where you might want to stick with DHTML scriptlets. First, they are the only choice if you want to remain compatible with Internet Explorer 4.0. Second, and more importantly, behaviors work fine when you have a single tag to enhance or customize, but what if you need to control several interacting elements such as <SPAN>, <DIV>, and <IMG> that work together to provide a completely custom component? You can still use behaviors, but you need to assign each component a specific style and arrange communication between them.
Figure 9: Scriptlets vs. Behaviors
Figure 9: Scriptlets vs. Behaviors

    Figure 9 shows how the two approaches differ. DHTML scriptlets are separate and self-contained HTML pages embedded in the host page; both the body and the script code are inside the scriptlet. To the HTML author, a scriptlet seems like a single entity despite the number of components it has and their silent interaction. In contrast, behaviors introduce a separation between the body and script code to manage its elements—the body is a native portion of the main page.

    Putting multiple elements together through behaviors sounds less reusable because the behaviors you're writing mainly serve the purpose of having the elements communicate. It's the union of both body elements and their respective behavior that constitutes a reusable entity. So I suggest you use DHTML scriptlets in the following circumstances:

When it comes to making a decision, also consider the following facts: DHTML scriptlets are thought to create new HTML components, while behaviors enhance the behavior of existing components. DHTML scriptlets also imply a new embedded HTML page, whereas behaviors pose a clear separation between the page content and its script code.

    Online references to the Internet Explorer 5.0 behaviors and the updated DHTML object model are available at http://msdn.microsoft.com/workshop/author/om/doc_object.asp. Since behaviors are a new innovation with Internet Explorer 5.0, some changes have been made to the Internet Explorer 4.0 DHTML object model to support them. The list of new methods and properties is shown in Figure 10. Notice the URN (Uniform Resource Name) function listed at the bottom of Figure 10. URNs are unique names that identify behaviors when attached to a given HTML element. I'll talk more about them shortly.

From Windows Script Components to HTC

    With the release of Internet Explorer 5.0 beta 2, Windows Script Components are no longer the only way to implement behaviors. They're still supported and have been improved in both performance and features, but you can now create behaviors with HTML Components (HTCs). HTCs are HTML-like files with a looser syntax than XML. In an HTC, <IMPLEMENTS> and <SCRIPTLET> are not recognized by the Internet Explorer 5.0 beta 2 parser and are skipped over.

    The main element in an HTC file is the <SCRIPT> block. Any code within the <SCRIPT> block that's not included in any function executes as soon as the page is loaded. Other commonly used tags are listed in Figure 11.

    Here's a typical layout for an HTC file:
<PUBLIC:HTC URN="MyBehavior">    
 <SCRIPT LANGUAGE="JScript">    
 </SCRIPT>
 </PUBLIC:HTC>
The HTC block is not strictly required and can be omitted. It just contains the URN attribute. The URN attribute serves to identify the behavior and is particularly useful when an event is raised to the host page but the element has many behaviors attached. The srcURN property lets the element distinguish which behavior is responsible for it.

    Functionally speaking, there's no difference between the HTC syntax and its Windows Script Component counterpart. When you want to refer the element that's attached to the behavior, you can use the element keyword. In general, I'd say that HTC seems simpler, more relaxed, and a bit more intuitive. Although I have no knowledge of the underlying implementation, lines like these

<PUBLIC:EVENT NAME="onResultChange" ID="rcID" />
 <PUBLIC:ATTACH EVENT="onclick" HANDLER="doCalc" />
remind me of MFC or ATL macros that simply save you from some boilerplate code. They aren't introducing new logic, but compressing more text into a single, sometimes parametric, expression. Figure 12 shows how to rewrite the Windows Script Component in Figure 6 as an HTC file.

Web Tooltips

    Among the samples available on MSDN, there's one that shows you how to create a tooltip maker. I'll rewrite it from scratch and provide a slightly different interface.

    The tooltip is implemented as a <SPAN> tag silently added to the page by the behavior. Initially, this tag is inserted at the beginning of the page with the absolute positioning flag set so it's easy to move it around later.

var coll = document.all("TipText");
 if(coll == null) {
   document.body.insertAdjacentHTML ("AfterBegin", 
        "<span id=TipText \
               style=position:absolute \
               display:none></span>");
 }
<SPAN> has the TipText ID and is not displayed by default. Since it's a <SPAN> tag, there's no problem with the text it can display; any HTML-compliant string is supported through the innerHTML property.

    In the test page, I have code like this:

.Tooltip {
   behavior:url(tooltip.wsc);
 }
 •••
 <table border="0">
 <tr>
 <td><img class="tooltip" src=mind.gif 
        tip="<img src=ms.gif> Internet Developer"></td>
 <td><img class="tooltip" src=msj.gif 
        tip="<i><b>Microsoft</b></i> Systems Journal"></td>
 </tr>
 </table>
The two <IMG> tags have the tooltip style that evaluates to the tooltip.wsc behavior. It reads in the content of the tip attribute and displays that HTML text when the mouse passes over the element. Tooltip works like the title or alt attributes, but also supports HTML strings instead of plain ASCII text. Figure 13 gives you an idea of what's going on. The full source code for the Web Tooltip behavior is in this month's source code.
Figure 13: Testing Tooltip Behavior
Figure 13: Testing Tooltip Behavior

    To learn more about all the programming aspects of Internet Explorer 5.0, you can check the documentation available on MSDN. Also look for the book Programming Microsoft Internet Explorer 5.0, by Scott Roberts, due out soon from Microsoft Press.

Conclusion

    Internet Explorer 5.0 goes much further than its predecessors in building a real development platform for client Web applications. Consider the following:

Internet Explorer 5.0 is a kind of runtime engine that hosts DHTML code as the front end of distributed DNA-compliant applications. With DHTML and its derivatives, now more than ever, you can build powerful client-side applications that need only a browser to run.

    Despite its strengths, there's a weak link in the Internet Explorer 5.0 chain. In my opinion, Internet Explorer 5.0 should reinforce the way Web pages can access remote data. Data binding and remote scripting are fully functional examples of technologies that can bring the traditional computer science metaphor to the Web. While these technologies specifically address different aspects of Web programming, they both ask some server-side module to return data without round-trips. Using data binding and remote scripting is not particularly difficult, but a better and more consistent mechanism (a behavior, perhaps) to accomplish this task is at the top of my wish list.

MSDN
http://www.microsoft.com/windows/ie/ie5/default.asp

    

From the April 1999 issue of Microsoft Internet Developer.