10.5 Dynamic Styles
An element's style can be changed dynamically. Often such a change is made in response to user events, which we discuss in Chapter 11. Such style changes can create many effects, including mouse hover effects, interactive menus, and animations. Figure 10.4 is a simple example that changes the background-color style property in response to user input.
1 <?xml version = "1.0" encoding = "utf-8"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 5 <!-- Fig. 10.4: dynamicstyle.html --> 6 <!-- Dynamic styles. --> 7 <html xmlns = "http://www.w3.org/1999/xhtml"> 8 <head>
Fig. 10.4. Dynamic styles. (Part 1 of 2.)
9 <title>Dynamic Styles</title> 10 <script type = "text/javascript"> 11 <!-- 12 function start() 13 { 14 var inputColor = prompt( "Enter a color name for the " + 15 "background of this page", "" ); 16 document.body.style.backgroundColor = inputColor; 17 } // end function start 18 // --> 19 </script> 20 </head> 21 <body id = "body" onload = "start()"> 22 <p>Welcome to our website!</p> 23 </body> 24 </html>
a)
b)
Fig. 10.4. Dynamic styles. (Part 2 of 2.)
Function start (lines 12–17) prompts the user to enter a color name, then sets the background color to that value. [Note: An error occurs if the value entered is not a valid color.] We refer to the background color as document.body.style.backgroundColor—the body property of the document object refers to the body element. We then use the style property (a property of most XHTML elements) to set the background-color CSS property. This is referred to as backgroundColor in JavaScript—the hyphen is removed to avoid confusion with the subtraction (-) operator. This naming convention is consistent for most CSS properties. For example, borderWidth correlates to the border-width CSS property, and fontFamily correlates to the font-family CSS property. In general, CSS properties are accessed in the format node.style.styleproperty.
Figure 10.5 introduces the setInterval and clearInterval methods of the window object, combining them with dynamic styles to create animated effects. This example is a basic image viewer that allows you to select a Deitel book cover and view it in a larger size. When one of the thumbnail images on the right is clicked, the larger version grows from the top-left corner of the main image area.
1 <?xml version = "1.0" encoding = "utf-8"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 5 <!-- Fig. 10.5: coverviewer.html --> 6 <!-- Dynamic styles used for animation. --> 7 <html xmlns = "http://www.w3.org/1999/xhtml"> 8 <head> 9 <title>Deitel Book Cover Viewer</title> 10 <style type = "text/css"> 11 .thumbs { width: 192px; 12 height: 370px; 13 padding: 5px; 14 float: left } 15 .mainimg { width: 289px; 16 padding: 5px; 17 float: left } 18 .imgCover { height: 373px } 19 img { border: 1px solid black } 20 </style> 21 <script type = "text/javascript"> 22 <!-- 23 var interval = null; // keeps track of the interval 24 var speed = 6; // determines the speed of the animation 25 var count = 0; // size of the image during the animation 26 27 // called repeatedly to animate the book cover 28 function run() 29 { 30 count += speed; 31 32 // stop the animation when the image is large enough 33 if ( count >= 375 ) 34 {
Fig. 10.5. Dynamic styles used for animation. (Part 1 of 4.)
35 window.clearInterval( interval ); 36 interval = null; 37 } // end if 38 39 var bigImage = document.getElementById( "imgCover" ); 40 bigImage.style.width = .7656 * count + "px"; 41 bigImage.style.height = count + "px"; 42 } // end function run 43 44 // inserts the proper image into the main image area and 45 // begins the animation 46 function display( imgfile ) 47 { 48 if ( interval ) 49 return; 50 51 var bigImage = document.getElementById( "imgCover" ); 52 var newNode = document.createElement( "img" ); 53 newNode.id = "imgCover"; 54 newNode.src = "fullsize/" + imgfile; 55 newNode.alt = "Large image"; 56 newNode.className = "imgCover"; 57 newNode.style.width = "0px"; 58 newNode.style.height = "0px"; 59 bigImage.parentNode.replaceChild( newNode, bigImage ); 60 count = 0; // start the image at size 0 61 interval = window.setInterval( "run()", 10 ); // animate 62 } // end function display 63 // --> 64 </script> 65 </head> 66 <body> 67 <div id = "mainimg" class = "mainimg"> 68 <img id = "imgCover" src = "fullsize/iw3htp4.jpg" 69 alt = "Full cover image" class = "imgCover" /> 70 </div> 71 <div id = "thumbs" class = "thumbs" > 72 <img src = "thumbs/iw3htp4.jpg" alt = "iw3htp4" 73 onclick = "display( 'iw3htp4.jpg' )" /> 74 <img src = "thumbs/chtp5.jpg" alt = "chtp5" 75 onclick = "display( 'chtp5.jpg' )" /> 76 <img src = "thumbs/cpphtp6.jpg" alt = "cpphtp6" 77 onclick = "display( 'cpphtp6.jpg' )" /> 78 <img src = "thumbs/jhtp7.jpg" alt = "jhtp7" 79 onclick = "display( 'jhtp7.jpg' )" /> 80 <img src = "thumbs/vbhtp3.jpg" alt = "vbhtp3" 81 onclick = "display( 'vbhtp3.jpg' )" /> 82 <img src = "thumbs/vcsharphtp2.jpg" alt = "vcsharphtp2" 83 onclick = "display( 'vcsharphtp2.jpg' )" /> 84 </div> 85 </body> 86 </html>
Fig. 10.5. Dynamic styles used for animation. (Part 2 of 4.)
a) The cover viewer page loads with the cover of this book.
b) When the user clicks the thumbnail of C How to Program, the full-size image begins growing from the top-left corner of the window.
Fig. 10.5. Dynamic styles used for animation. (Part 3 of 4.)
c) The cover continues to grow.
d) The animation finishes when the cover reaches its full size.
Fig. 10.5. Dynamic styles used for animation. (Part 4 of 4.)
The body (lines 66–85) contains two div elements, both floated left using styles defined in lines 14 and 17 in order to present them side by side. The left div contains the full-size image iw3htp4.jpg, which appears when the page loads. The right div contains six thumbnail images which respond to the click event by calling the display method and passing it the filename of the corresponding full-size image.
The display function (lines 46–62) dynamically updates the image in the left div to the one corresponding to the user's click. Lines 48–49 prevent the rest of the function from executing if interval is defined (i.e., an animation is in progress.) Line 51 gets the left div by its id, imgCover. Line 52 creates a new img element. Lines 53–55 set its id to imgCover, set its src to the correct image file in the fullsize directory, and set its required alt attribute. Lines 56–59 do some additional initialization before beginning the animation in line 61. To create the growing animation effect, lines 57–58 set the image width and height to 0. Line 59 replaces the current bigImage node with newNode (created in line 52), and line 60 sets count, the variable that controls the animation, to 0.
Line 61 introduces the window object's setInterval method, which starts the animation. This method takes two parameters—a statement to execute repeatedly, and an integer specifying how often to execute it, in milliseconds. We use setInterval to call function run every 10 milliseconds. The setInterval method returns a unique identifier to keep track of that particular interval—we assign this identifier to the variable interval. We use this identifier to stop the animation when the image has finished growing.
The run function, defined in lines 28–42, increases the height of the image by the value of speed and updates its width accordingly to keep the aspect ratio consistent. Because the run function is called every 10 milliseconds, this increase happens repeatedly to create an animated growing effect. Line 30 adds the value of speed (declared and initialized to 6 in line 24) to count, which keeps track of the animation's progress and dictates the current size of the image. If the image has grown to its full height (375), line 35 uses the window's clearInterval method to stop the repetitive calls of the run method. We pass to clearInterval the interval identifier (stored in interval) that setInterval created in line 61. Although it seems unnecessary in this script, this identifier allows the script to keep track of multiple intervals running at the same time and to choose which interval to stop when calling clearInterval.
Line 39 gets the image and lines 40–41 set its width and height CSS properties. Note that line 40 multiplies count by a scaling factor of .7656 in order to keep the ratio of the image's dimensions consistent with the actual dimensions of the image. Run the code example and click on a thumbnail image to see the full animation effect.
This section demonstrated the concept of dynamically changing CSS styles using JavaScript and the DOM. We also discussed the basics of how to create scripted animations using setInterval and clearInterval.