Section IV.3. Image Swapping


IV.3. Image Swapping

As precursors to true DHTML powers of more recent browsers, Navigator 3 (and Internet Explorer 3.01 for the Macintosh only) gave us a glimpse of things to come with image swapping. The basis for this technique is a document object model that defines an img element as an object whose properties can be changed on the fly. One of those properties, src, defines the URL of an image loaded initially by virtue of an <img> tag and currently displayed in the page. Change that property and the image changes, within the same rectangular space defined by the <img> tag's height and width attributes (or, lacking those attribute settings, the first image's dimensions as calculated by the browser), while all the other content around it stays put. In browsers that reflow dynamic content, you can swap images of different sizes if you like, and the surrounding content adjusts its layout accordingly.

Working in tandem with the img element object is the static Image object from which new "virtual" images can be created in the browser's memory with the help of scripts. These kinds of images do not appear in the document, but can be scripted to preload images into the browser's image cache as the page does its original download. Thus, when it comes time to swap an image, the switch is nearly instantaneous because there is no need for network access to grab the image data.

The example in this section shows you how to precache and swap images for the buttons of an imaginary navigation menu. There are three button-looking imagesHome, Catalog, and About Us. As the user rolls the mouse atop a button, a highlighted ("on") version of the button appears in the image space; as the mouse rolls off the button, the original unhighlighted ("off") version reappears. Importantly, the code is written so that standard HTML markup is used for the links, and only browsers supporting the necessary scripting facilities add the rollover feature. Here is the HTML that will be addressed by the rollover scripts:

 <a href="index.html"><img       height="20" width="80" border="0" src="/books/2/570/1/html/2/img/home_off.jpg" alt="Home"></a> <a href="catalog.html"><img       height="20" width="80" border="0" src="/books/2/570/1/html/2/img/catalog_off.jpg" alt="Catalog"></a> <a href="about.html"><img       height="20" width="80" border="0" src="/books/2/570/1/html/2/img/about_off.jpg" alt="About Us"></a> 

The only noteworthy items about this HTML is that each img element has its unique ID (whose identifier is part of the image's file name for both "on" and "off" versions) and that all share the same class attribute value (swappable). Scripts that modify the behaviors of the images identify their targets by their shared class name.

IV.3.1. Preparing for the Initialization

To keep the scripting away from the markup, the initialization routine occurs after the page loads, that is, when the window's load event fires. The mechanism used in this example (described more fully in Online Section VI) employs a custom API function to accommodate both the W3C DOM and Microsoft event models. The addEvent( ) function (which can be invoked by any other routines in the page's scripts) handles the browser differences. For this example, a call to the init( ) function is bound to the window's load event as follows:

 function addEvent(elem, evtType, func, capture) {    capture = (capture) ? capture : false;    if (elem.addEventListener) {       elem.addEventListener(evtType, func, capture);    } else if (elem.attachEvent) {       elem.attachEvent("on" + evtType, func);    } } function init( ) {    // initialize rollover object    rollover.init( ); } addEvent(window, "load", init); 

IV.3.2. Defining a "Rollover" Object

All modification to the img elements occurs in the rollover object, shown in Example IV-6. Among the tasks assumed by this single object are the following:

  • Creating an associative array of offscreen image objects

  • Precaching the "on" images

  • Binding mouse event handlers to affected images

  • Handling mouse events

The rollover object is created as the page loads, and is initialized after the page has loaded (via a call to rollover.init( )).

Example IV-6. A generic rollover object

 // rollover object var rollover = {    // image directory path    imgPath : "img/",    // create associative arrays for images    imagesNormal : new Object( ),    imagesHilite : new Object( ),    // invoked by img mouse events    setImage : function(elemID, img) {       document.getElementById(elemID).src = img;    },    // initialize    init : function( ) {       if (document.getElementById) {          var imgID;          var imgs = document.body.getElementsByTagName("img");          for (var i = 0; i < imgs.length; i++) {             if (imgs[i].className == "swappable") {                // fill arrays and pre-cache "_on" images                imgID = imgs[i].id;                this.imagesNormal[imgID] = new Image( );                this.imagesNormal[imgID].src = this.imgPath + imgID + "_off.jpg";                this.imagesHilite[imgID] = new Image( );                this.imagesHilite[imgID].src = this.imgPath + imgID + "_on.jpg";                // assign image swapping event handlers to img elements                addEvent(imgs[i], "mouseover", new Function("rollover.setImage('" +                    imgID + "','" + this.imagesHilite[imgID].src + "');"));                addEvent(imgs[i], "mouseout", new Function("rollover.setImage('" +                    imgID + "','" + this.imagesNormal[imgID].src + "');"));             }          }       }    } } 

The imgPath property contains a string with the path (relative or absolute, as needed for your server directory structure) to the directory containing all images used in the rollover effect. Two associative arrays (imagesNormal and imagesHilite) are initialized as empty objects whose properties will be filled when the init( ) method runs. The setImage( ) method is the one called by both the mouseover and mouseout events of the rollover images. This method receives an ID of an img element and the URL of the image to be assigned to the element's src property.

Most of the hard work occurs in the init( ) method. Limited to browsers that support the W3C DOM document.getElementById( ) method, it begins by obtaining an array of all img elements in the document. Next it loops through them all in search of those whose class attribute is swappable. It uses the ID of each image to assemble the URL of each image file for both states of each button. Assigning a URL to the src property of an instance of an Image object causes the browser to download the image into the image cache. Having the image already in the cache avoids a delay in the first display of the "on" image. Lastly, each img element has two event handlers bound to it. Because the event handlers will be invoked from outside of the context of the rollover object, the call to the setImage( ) method includes an explicit reference to the rollover object. Note that event binding occurs only in browsers that support the basic W3C DOM syntax; if the events had been assigned as attributes within the <a> or <img> tags, older browsers would react to those events, and your scripts would have to perform compatibility filtering with each event firing. With the approach in Example IV-6, older browsers don't respond to those events at all (yet the links work just fine for everyone).

IV.3.3. Rollovers and the Status Bar

Versions of image rollover scripts in previous editions of Dynamic HTML: The Defintive Referencein addition to being more invasive in the markupincluded a routine for modifying the text that displayed in the browser's status bar during a mouse rollover. The ability to display status bar text other than the actual URL of a link has been removed from most modern browsers.

Although one can imagine good uses of that power (e.g., providing a more friendly message about the destination), the capability has been abused by those who prefer to trick users. It's not uncommon, for example, for a phishing email message delivered in HTML to include a link whose in-page text looks to be a trusted site, but whose href attribute points to a different site that tries to install malware onto all visitors' PCs. It is too easy to code such a link with mouseover events that modify the window.status property to display the trusted site's URL, rather than the URL of the actual destination. To prevent this type of spoofing from tricking unsuspecting users, browser makers have simply disabled this scriptable feature.

IV.3.4. Internet Explorer Caching Issues

If image preloading does not appear to work for your pages in IE for Windows, your server may be returning HTTP 1.1 headers that instruct the browser to check with the server each time an image URL is changed. This can cause severe thrashing behavior with mouse rollovers because the mouseover event fires repeatedly while the mouse is atop the element, forcing repeated server requests.

You may be able to override the server settings by including a meta element in your document that specifies an extended expiration date, such as the following:

 <meta http-equiv="EXPIRES" content="Fri 31 Dec 2010 23:00:00 GMT"> 

But controlling caching from the server is a better solution.




Dynamic HTML. The Definitive Reference
Dynamic HTML: The Definitive Reference
ISBN: 0596527403
EAN: 2147483647
Year: 2004
Pages: 120
Authors: Danny Goodman

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net