reptile7's JavaScript blog
Friday, November 11, 2011
The Banner Loop, Part 3
Blog Entry #232

Is it necessary to go through the create-your-own-object rigmarole in assembling the banner animation of HTML Goodies' "Accessible JavaScript 101: Rotating Banners" tutorial? Not at all, folks...

A classical approach

The introduction for Blog Entry #230 briefly noted that we had previously coded an image-cycle animation in Blog Entry #147. Can we adapt the code for that animation to the "Rotating Banners" animation? You betcha:

Affiliate Links

Search Web with GoogleSearch Web with Yahoo!Search Web with MSN
The animation part (vis-à-vis the accessibility part, vide infra) of the above demo requires only one image-link placeholder: <div id="banners"> <a id="bannerLink" href=""> <img id="bannerImage" src="googlelogo.png" alt="Search Web with Google" onload="window.setTimeout('animate( );', delay);" /> </a> </div> The banner images are initially accessed via the following preloading code: var delay = 1000; var sponsor = ["google", "yahoo", "msn"]; var theImages = new Array( ); for (i = 0; i < sponsor.length; i++) {     theImages[i] = new Image( );     theImages[i].src = sponsor[i] + "logo.png"; } As shown, the images can be preloaded automatedly if we pre-array the sponsor parts of their file names. (In practice for the preceding demo, the theImages[i].srcs are set discretely and not automatedly as the logo images have irregular URLs.) The animation's first frame displays the Google banner and is set by the above HTML. For subsequent frames, an imgObject.onload-triggered animate( ) function uses an imageNum index to write the bannerImage img's src and alt values and the bannerLink link's href value. var imageNum = 0; var altData = ["Google", "Yahoo!", "MSN"]; function animate( ) {     imageNum++;     document.getElementById("bannerImage").src = theImages[imageNum].src;     document.getElementById("bannerImage").alt = "Search Web with" + altData[imageNum];     document.getElementById("bannerLink").href = "http://www." + sponsor[imageNum] + ".com";     if (imageNum == 2) imageNum = -1; } The Blog Entry #147 animation is based on a Netscape classical JavaScript animation example that dates to the JavaScript 1.1 Guide/Reference. The link to the Netscape example in Blog Entry #147 is dead has recently been updated and now points to an archived copy of the original page; as far as I know, the Nihonsoft guys no longer host any of the JavaScript specifications. The DOM sector of the Mozilla Developer Network's Web site does not feature the Netscape example nor does it have anything to say more generally about the use and application of Image( ) constructors (OK, there is one small Image( ) example on this page), but maybe that'll change in the future given that the W3C has brought the Image( ) constructor into HTML5. Accessibility If you'd like all of the banners to be visible for users without JavaScript support, just follow these simple steps: (1) Add/append the other two image-links to the banners div container. ... <a href=""><img src="yahoologo.png" alt="Search Web with Yahoo!" /></a> <a href=""><img src="msnlogo.png" alt="Search Web with MSN"></a> </div> (2) To mimic the original ul/li formatting, give the banners anchor elements a #banners a { display: block; } style. For users with JavaScript support, zero out the added Yahoo! and MSN image-links via: window.onload = function ( ) {     var bannerLinks = document.getElementById("banners").getElementsByTagName("a");     for (i = 1; i < bannerLinks.length; i++)         bannerLinks[i].style.display = "none"; }   A(nother) DOM approach "But I want a fancy shmancy DOM way to do it." Huh? Isn't the use of id identifiers and the getElementById( ) method good enough for you? We could have used name identifiers and the document.images[ ] and document.anchors[ ] collections* to access the banners, you know. (*These collections are in the HTML DOM but they are not of the DOM: they are legacy/for-backward-compatibility features that originated in JavaScript.) Very well, then. I've come up with another DOM-based approach (actually two closely related approaches, although I see them as the same approach) to the "Rotating Banners" animation that is in fact more straightforward than the foregoing classical animation approach. We saw in Blog Entry #230 that the original "Rotating Banners" code deals with the listElement unordered list and its contents on a node-by-node basis. Gratifyingly, the Core DOM Node interface features methods via which we can cycle the banners on an element-by-element basis and not have to worry about the end-of-line Text nodes that surround the banners. Suppose that in each animation iteration we could change banners by simply picking up the currently displaying banner and moving it to the end of the listElement list, thereby displaying the next banner: the appendChild( ) method will allow us to do precisely that. var listElement = document.getElementById("banners").getElementsByTagName("ul")[0]; var liElements = listElement.getElementsByTagName("li"); var firstBanner = liElements[0]; listElement.appendChild(firstBanner);

Affiliate Links

  • Search Web with Google
  • Search Web with Yahoo!
  • Search Web with MSN
Alternatively, we can 'go in reverse' if we want to, that is, we can change banners by picking up the last banner and moving it in front of the first banner: the insertBefore( ) method will do that for us. var lastBanner = liElements[2]; listElement.insertBefore(lastBanner, firstBanner); The appendChild( ) operation gives a listElement list that begins with two end-of-line characters whereas the insertBefore( ) operation gives a listElement list that ends with two end-of-line characters, which in neither case is a problem as those end-of-line characters will be ignored when the page is rendered. The insertBefore( ) banner order (Google to MSN to Yahoo!) differs from the appendChild( ) banner order (Google to Yahoo! to MSN), not that that's a big deal, of course. Accessibility Even if we give the listElement list a specific height:80px;, leaving the list's CSS overflow property at visible (the overflow value initially assigned to it by the browser) will ensure that all of the banners are visible for users without JavaScript support. For users with JavaScript support, running a for (i = 1; i < liElements.length; i++) liElements[i].style.display = "none"; loop statement in the animation's first frame will zero out the Yahoo! and MSN banners; for subsequent frames, liElements[0].style.display = "block"; liElements[liElements.length - 1].style.display = "none"; will switch on the new banner and switch off the old banner if you're cycling the banners via the appendChild( ) method whereas liElements[0].style.display = "block"; liElements[1].style.display = "none"; will do so if you're cycling the banners via the insertBefore( ) method.
We'll continue the 'rotation' theme in the following entry by taking up "Web Developer Class: Build Your Own JavaScript Content Rotator", the next Beyond HTML : JavaScript sector tutorial.


Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)