Because both script and content typically live together on a Web page, functionality can be broken inadvertently by writers and editors who are working on content. DHTML Behaviors provide a way to separate functionality from the content that it affects.
DHTML Behaviors can be created both with HTML Components (HTCs) and with traditional programming languages such as C++. We will focus on the use of HTCs, as C++ is beyond the scope of this book. (Find out more about using C++ to implement behaviors from the SBN Workshop. On the companion CD; see Workshop (References); DHTML, HTML, and CSS; DHTML Behaviors; C++ Reference.) HTCs are essentially standard HTML files containing script and some HTC-specific tags. Elements in other Web pages can then use the behavior CSS attribute to access the functionality contained in the HTC. HTCs can expose their properties, methods, and events (including custom events) to the containing page, and can in turn access the object model of the containing page. Code Listing 22-4 demonstrates a Web page containing an expanding/collapsing menu as well as methods and properties implemented through DHTML Behaviors. Figures 22-2 and 22-3 show the results.
Code Listing 22-4.
<HTML> <HEAD> <TITLE>Listing 22-4</TITLE> <STYLE> DIV {cursor:hand;margin-left:2em} .ExpandingHead{behavior:url(ExpMenu.htc)} </STYLE> </HEAD> <BODY> <DIV ID="Item1" CLASS="ExpandingHead"><B>Level 1 Item 1</B> <DIV>Level 2 Item 1</DIV> <DIV>Level 2 Item 2</DIV> <DIV CLASS="ExpandingHead"><B>Level 2 Item 3</B><BR> <DIV>Level 3 Item 1</DIV> <DIV>Level 3 Item 2</DIV> </DIV> <DIV>Level 2 Item 4</DIV> </DIV> <DIV CLASS="ExpandingHead"><B>Level 1 Item 2</B> <DIV>Level 2 Item 1</DIV> <DIV>Level 2 Item 2</DIV> </DIV> <FORM> <INPUT TYPE="BUTTON" VALUE="Run Item1.showChildren()" onclick="Item1.showChildren()"> <INPUT TYPE="BUTTON" VALUE="Display item1.iChildren" onclick="alert(Item1.iChildren)"> </FORM> </BODY> </HTML> |
Notice the simplicity of the code in the body of the page. Every item in the menu is a DIV element. If a menu item DIV element contains other nested items, it is given the ExpandingHead CLASS. This class is defined in the global style sheet at the top of the page. It contains the CSS attribute behavior that is directed to the file ExpMenu.htc.
Figure 22-2. The menu before a heading is clicked.
Figure 22-3. Code Listing 22-4 displays fully opened in Netscape Navigator.
The file ExpMenu.htc listed below and included on the companion CD as chap22/ExpMenu.htc contains the behavior itself.
<PUBLIC:HTC URN="www.microsoft.com"> <SCRIPT language="JavaScript"> attachEvent("onclick", toggleDisplay) function toggleDisplay(){ // Hide/unhide all child objects (start at 1 so heading is skipped) for (var i=1; i<children.length; i++){ children[i].style.display=(children[i].style.display==""?"none":"") } // Prevent click on sub item from collapsing whole menu if(window.event){window.event.cancelBubble=true} } // Collapse menu when first loaded toggleDisplay() function showChildren(){ // Return list of child items var Txt="" for(var i=1;i<children.length;i++){Txt+=(children[i].innerText+"\n")} alert(Txt) } iChildren=children.length </SCRIPT> <PUBLIC:METHOD NAME="showChildren" /> <PUBLIC:PROPERTY NAME="iChildren" /> </PUBLIC:HTC> |
The beginning and end tags for an HTML Component file are <PUBLIC:HTC URN =location> and </PUBLIC:HTC>. The URN attribute is used to specify a unique name for the component, which usually points to the location where the HTC is found. This attribute is helpful if you use multiple behaviors on the same element. It can be used in combination with the srcURN property of the event object to identify which behavior is acting at a particular time.
The majority of the functionality of the behavior is found in the SCRIPT block. The attachEvent method can be used to bind a function in the HTC to an event fired by the element that called the behavior. In our case, the toggleDisplay function in the behavior is bound to the onclick event on the DIV. This function toggles the contents of the DIV between being hidden and being visible when the DIV is clicked as shown in Figure 22-4.
Figure 22-4. The menu after Level 1 Item 1 is clicked.
After the SCRIPT block in the HTC, we see two tags. They both begin with the word PUBLIC, which makes them available to the hosting page. The METHOD element exposes the showChildren function to the containing Web page. This function can then be called as though it were a method of the element that calls the behavior. In Code Listing 22-4 there are two buttons after the collapsing menu. When clicked, the first button calls Item1.showChildren(). The Item1 DIV element has the ExpandingHead class, which links it to the ExpMenu behavior. Because the behavior exposes the showChildren method, it can be called directly as a method of the Item1 object. Figure 22-5 shows the resulting Alert dialog box.
Figure 22-5. The Alert dialog box displayed when the first button is clicked.
In the SCRIPT block in the HTC, an iChildren variable is created and set equal to the number of children contained by the Web page element that called the HTC. The PROPERTY element is then used to expose this value as a property of the element in the Web page. The second button in Code Listing 22-4 accesses this property through Item1.iChildren. The PROPERTY element can also be used by the HTC to read a property set on the calling element in the Web page. For example, if the DIV element had had the property FOO="Example" the following code snippet would create in the HTC a variable named FOO that was tied to the value set in the DIV element:
<PUBLIC:PROPERTY NAME="FOO" /> |
Behaviors can do far more than what is outlined here; you can find extensive references for behaviors on the SBN Workshop Web site. The Workshop also contains a number of sample behaviors, such as the SoundRollover behavior, which can be applied to an element to cause a noise when the mouse passes over it.
Internet Explorer 5 includes several default behaviors that provide a number of different services to Web pages. Some are described in Table 22-1.
Code Listing 22-5 demonstrates the use of the saveFavorite behavior. If users add this page to their favorites, any elements with the saveFavorite class fire the onsave event. This event causes the text field in Code Listing 22-5 to call the setAttribute method of the behavior, saving the value of the txt1 field in the name of txt1_ssve. When the user returns to the page by going to the entry in the favorites list, the onload event of the text field is fired and the getAttribute method of the behavior is used to retrieve the saved value.
Table 22-1 Internet Explorer Default Behaviors
Name | Description |
---|---|
clientCaps | Contains information about the features of the end user's browser (CLIENT CAPabilitieS) |
download | Allows a file to be downloaded and accessed through script and for a function to be run when the download is complete |
homePage | Allows you to check and set the user's home page (with the user's permission) |
saveFavorite | Allows you to control and save the state of a page when it is added to a user's favorites |
saveHistory | Allows you to control and save the state of a page when the user navigates away from the page |
saveSnapshot | Allows you to control the state of a page when the user saves a Web page to disk |
userData | Allows information to be saved for when a user returns to a Web page and allows for more flexibility and data storage than cookies |
Code Listing 22-5.
<HTML> <HEAD> <TITLE>Listing 22-5</TITLE> <STYLE> .saveFavorite {behavior:url(#default#saveFavorite)} </STYLE> </HEAD> <BODY> Uses saveFavorite: <INPUT ID="txt1" CLASS="saveFavorite" TYPE="text" onsave="this.setAttribute(`txt1_save',txt1.value)" onload="this.getAttribute(`txt1_save')"> </BODY> </HTML> |