Table of Contents | Previous Next |
9.2 Controlling objects with event handlersYou've already encountered some examples of mouse events and mouse control in Chapter 6. These examples are just special cases of event handlers. An event handler is basically a software tool used to handle application events that are generated normally by hardware devices such as the keyboard and mouse. For example, when a mouse runs over an object on a Web page, the browser will generate a mouse-over event. If you have the onmouseover handler installed, it will be triggered and perform appropriate actions (script statements or functions) designed by the author. An event model is the internal structure of a browser dealing with how an event handler is handled. Since events can be intercepted by handlers at any level, different event models may produce different results. This type of inconsistency could be quite difficult to find and correct. For Web programmers, special care is necessary when setting up general event handlers, as compatibility, especially backward browser compatibility, is an important issue. More details on event models are given later in section 9.3. For now, let's consider some event handlers and get ready for some action. 9.2.1 Basic event handlersBoth IE and NS provide a rich set of event handlers to cover most hardware events. Most of them are the same and follow the W3C standard. However, they all have their own extensions to include new features and to ensure some sort of backward compatibility with their own kind. The standard W3C event document is big, so even to provide a listing of all the commands and specifications is beyond the scope of this chapter. In this section, we classify some frequently used and widely supported event handlers into three categories, namely, "Mouse and Keyboard," "Document and Browser Window," and "Form-Related" event handlers. The mouse and keyboard event commands are listed in Table 9.1.
These commands are frequently used in all aspects of Web programming. One good example is in the use of buttons such as <input type="button" onclick="anotherFunction()"> Another example is to change an image when the mouse runs over it: <img src="img01.gif" name="myImg" id="myImg" onmouseover='document.getElementById("myImg").src="img02.gif"' /> These are our old friends and used everywhere on the Web. Together with the mouse and keyboard, you also need some event commands to control how the document should be loaded and how the browser window should behave. In many cases, these event controls are used inside the body element to monitor the behavior of the browser window to see, for example, whether or when
The event commands are listed in Table 9.2.
Other popular handlers on the Web are the form control handlers. They are used to control the effects of a form such as submission and validation (see Table 9.3).
Again, there are many more event handlers available on both the IE and NS. For practical purposes, these built-in handlers are standard, widely used, and handy tools for many Web programming situations. Event handlers play an essential part in any interactive programming on the Web. They are the vital links between XHTML, scripting languages, and your hardware devices to provide real-time interactions between the user and your Web page. Let's now look at some examples. 9.2.2 A page to capture and test various eventsTo demonstrate the idea and to put some of the handlers into action, a page is developed to show how to handle some keyboard, mouse, and browser window events. This page can also be used to test the capability of browsers on handling hardware events. Consider the page ex09-04.htm below: Example: ex09-04.htm - A Page To Test Various Events 1: <?xml version="1.0" encoding="iso-88591"?> 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 3: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 5: <head><title> A Page To Test Various Events - ex0904.htm </title></head> 6: 7: <body style="background:#000088;font-family:arial;font-size:28pt; 8: color:#ffff00;font-weight:bold;text-align:center" 9: onmousedown="events(1)" 10: onmouseup="events(2)" 11: onkeydown="events(3)" 12: onkeyup="events(4)" 13: ondblclick="events(5)" 14: onresize="events(6)" 15: onscroll="events(7)" 16: > 17: <div align="center">Basic Event Handlers</div><br /> 18: <table style="font-size:18pt"><tr><td width="200"> 19: onmousedown()</td><td width="200">onmouseup</td></tr> 20: <tr><td>onkeydown()</td><td>onkeyup()</td></tr> 21: <tr><td>onresize()</td><td>onscroll()</td></tr> 22: </table><br /> 23: <div style="font-size:18pt;color:#00ff00" 24: id="eventMsg" name="eventMsg"></div><br /> 25: <div style="font-size:18pt">One of the above events has 26: been captured.The event message is displayed in green color.<br /> 27: 28: <script> 29: Msg = new Array() 30: Msg[1]="A mouse button is down." 31: Msg[2]="A mouse button has just been released." 32: Msg[3]="A keyboard key has been pressed." 33: Msg[4]="A keyboard key has been released." 34: Msg[5]="The mouse has been double-clicked." 35: Msg[6]="The window has been resized." 36: Msg[7]="The window scrollbar position has been changed." 37: 38: function events(msgId) 39: { 40: document.getElementById("eventMsg").innerHTML=Msg[msgId] 41: } 42: </script> 43: </body> 44: </html> You can call this page a dedicated event tester since its only real function is to trap events. In order to capture the event on the entire page, we put the handlers inside the body element. There are six of them as illustrated in lines 915. The first handler is onmousedown="events(1)" This command captures the moment when you hold down a mouse button inside the page. The event triggers the function events()with argument "1." This function (lines 3841) has only one statement and that is to output the message Msg[1] to the location with id="eventMsg". The message Msg[1] is defined in line 30 and you will see a message "A mouse button is down." on the screen. This mouse-down handler will be used later to catch and hold a flying object. A screen shot of this event is shown in Fig. 9.4. Some other events have also been captured and are shown in Figs 9.59.7. Figure 9.4. ex09-04.htmFigure 9.5. Key pressedFigure 9.7. Window scrollFigure 9.6. Window resize9.2.3 Some jumping charactersTo apply handlers to moving objects, let's consider a simple example with jumping characters. This page contains three characters "W," "e," and "B," in image format. When a mouse click or a key press event occurs, some of the characters will move. Some simple controls are also added in this page so that the same event may trigger different motions. The code of this page is listed in ex09-05.htm. Example: ex09-05.htm - Jumping Characters 1: <?xml version="1.0" encoding="iso-88591"?> 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 3: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 5: <head><title> Jumping Characters - ex0905.htm </title></head> 6: 7: <script src="ex09-05.js"></script> 8: <body style="background:#dddddd;font-family:arial;font-size:28pt; 9: color:#000088;font-weight:bold;text-align:center" 10: onclick="selectAction()" onkeypress="selectAction()"> 11: 12: <div align="center">Jumping Characters<br /> 13: <span style="font-size:18pt;color:#880000">Click Left Mouse Or 14: <br /> Press Keyboard </span> 15: </div> 16: 17: <div id="char01" name="char01" 18: style="position: absolute;top: 300px;left: 50px"> 19: <img src="sspic01.gif" alt="pic" height="130" width="130" /></div> 20: 21: <div id="char02" name="char02" 22: style="position: absolute;top: 330px;left: 160px"> 23: <img src="sspic02.gif" alt="pic" height="100" width="100" /></div> 24: 25: <div id="char03" name="char03" 26: style="position: absolute;top: 310px;left: 255px"> 27: <img src="sspic03.gif" alt="pic" height="120" width="120" /></div> 28: 29: </body> 30: </html> This page contains three images. The first one, sspic01.gif as defined in lines 1719, is a picture of the character "W." This picture is located at the top left position (300, 50). The second and third pictures are defined in a similar pattern. The following event handlers are defined in line 10: onclick="selectAction()" onkeypress="selectAction()" This statement captures any mouse click or key press event and triggers the function selectAction() as defined in an external file ex09-05.js. The listing of this file is Example: ex09-05.js - The ECMAScript For ex09-05.htm 1: function mChar03() 2: { 3: var ixDelta = 20 4: var iyDelta = -35 5: lxPos = parseInt(document.getElementById("char03").style.left)+ixDelta 6: lyPos = parseInt(document.getElementById("char03").style.top)+iyDelta 7: if (lxPos >= 400 || lyPos < 10) 8: { 9: lxPos=250 10: lyPos=310 11: document.getElementById("char03").style.left = lxPos + "px" 12: document.getElementById("char03").style.top = lyPos + "px" 13: return 14: } 15: document.getElementById("char03").style.left = lxPos + "px" 16: document.getElementById("char03").style.top = lyPos + "px" 17: setTimeout("mChar03()",50) 18: } 19: 20: var ixDelta2 =-0.2 21: function mChar01() 22: { 23: ixDelta2 = 0.2 + ixDelta2 24: 25: lxPos = -150 * Math.cos(ixDelta2) + 200 26: lyPos= -150* Math.sin(ixDelta2) + 300 27: 28: if (lxPos >= 400 || lyPos > 300) 29: { 30: lxPos= 50 31: lyPos=300 32: ixDelta2 =-0.2 33: document.getElementById("char01").style.left = lxPos + "px" 34: document.getElementById("char01").style.top = lyPos + "px" 35: return true 36: } 37: document.getElementById("char01").style.left = lxPos + "px" 38: document.getElementById("char01").style.top = lyPos + "px" 39: setTimeout("mChar01()",50) 40: } 41: 42: var sAction=1 43: function selectAction() 44: { 45: if (sAction ==1){ 46: sAction = 2 47: mChar03() 48: } else { 49: sAction = 1 50: mChar01() 51: } 52: } The selectAction() function in lines 4252 of this file is actually a controller used to decide which object should be animated. If the variable sAction equals 1, the function mChar03() is called to animate the "B" picture. Otherwise the mChar01() function is called to move the "W" picture. The swap use of the sAction allows you to have different animations every time an event occurs. The motion inside the function mChar03() is in a straight line. By adding the following top and left values to the (top, left) coordinates of the object in each step
a constant movement is achieved and generates a straight line motion effect. The function mChar01() defined in lines 2140 is a circular motion. The basic equations defining the motion are
where variable R is the radius and t is time. In terms of programming, we have ixDelta2 = 0.2 + ixDelta2 (i.e. variable t) lyPos= -150 * Math.sin(ixDelta2) + 300 (i.e. variable Y) lxPos = -150 * Math.cos(ixDelta2) + 200 (i.e. variable X) We have used the radius R=150 in this case. The negative values of the radius and the translation at the end of the equations are used to adjust the motion so that the picture "W" appears to jump from the front to the back. The clipping conditional statement in line 28 is to make sure that the object moves back to its original position after the jump. This function is called regularly once every 50 milliseconds to create realistic motion until one of the clipping conditions is satisfied. Since the event handlers react quicker than the setTimeout() function, if you press two keys simultaneously you will see two characters move together. Some screen shots are given in Figs 9.8 and 9.9. Figure 9.8. ex09-05.htmFigure 9.9. Picture "W" jumpsThe next example shows how to select and drive multiple objects by using the mouse. 9.2.4 Selecting and driving objects with the mouseAnother basic technique of moving objects is to guide an object, or entity, with a mouse click. When you click your mouse, the selected object will go to your mouse point. To illustrate this technique, the images in the previous example are used as objects and some buttons are added so that a selection can be made. The XHTML interface program is listed in ex09-06.htm. Example: ex09-06.htm - Picking And Driving Objects 1: <?xml version="1.0" encoding="iso-88591"?> 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 3: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 5: <head><title> Picking and Driving Objects - ex0906.htm </title></head> 6: <style> 7: .butSt{background-color:#aaffaa;font-family:arial;font-weight:bold; 8: font-size:16pt;color:#880000;width:180px;height:40px}</style> 9: <script src="ex0906.js"></script> 10: <body style="background:#dddddd;font-family:arial;font-size:28pt; 11: color:#000088;font-weight:bold;text-align:center" > 12: 13: <div align="center">Select & Drive Objects With Mouse <br /> 14: <span style="font-size:18pt;color:#880000">Click Mouse To Drive Object 15: <br /> Press Button To Make Selection</span></div> 16: 17: <div id="char01" name="char01" 18: style="position: absolute;top: 300px;left: 50px"> 19: <img src="sspic01.gif" alt="pic" id="imgW" name="imgW" 20: height="130" width="130" /></div> 21: <div id="char02" name="char02" 22: style="position: absolute;top: 330px;left: 160px"> 23: <img src="sspic02.gif" alt="pic" id="imgE" name="imgE" 24: height="100" width="100" /></div> 25: <div id="char03" name="char03" 26: style="position: absolute;top: 310px;left: 255px"> 27: <img src="sspic03.gif" alt="pic" id="imgB" name="imgB" 28: height="120" width="120" /></div> 29: 30: <input type="button" class="butSt" 31: style="position: absolute;top:180px;left:450px" 32: value="Move W" onclick="buttonClk(1)" /> 33: <input type="button" class="butSt" 34: style="position: absolute;top:230px;left:450px" 35: value="Move e" onclick="buttonClk(2)" /> 36: <input type="button" class="butSt" 37: style="position: absolute;top:280px;left:450px" 38: value="Move B" onclick="buttonClk(3)" /> 39: <input type="button" class="butSt" 40: style="position: absolute;top:330px;left:450px" 41: value="Reset Pictures" onclick="resetPic()" /> 42: </body> 43: </html> The first part of this page (lines 1728) is basically the same as that in example ex09-05.htm to define three images, "W," "e," and "B." The second part in lines 3041 defines four buttons. The first button (lines 3032) <input type="button" class="butSt" style="position: absolute;top:180px;left:450px" value="Move W" onclick="buttonClk(1)" /> is located at the top left coordinate (180, 450) and has the name "Move W." When this button is pressed, the function buttonClk(1) is called and changes the selected object to "W." Therefore the motion applies to the new selected object. The second (lines 3335) and the third buttons (lines 3638) are defined in a similar fashion. The last button activates the function resetPic() to restore all three pictures to their original position. If a mouse click takes place on the page, but not on the buttons, the function mouseClk() is executed to drive the selected object to the mouse point, creating a motion effect. Both buttonClk() and mouseClk() functions are defined in the external script function ex09-06.js. Before the program is listed, some screen shots are shown in Figs 9.10 and 9.11. Figure 9.10. ex09-06.htmFigure 9.11. Driving objectsThe external script file ex09-06.js is listed as follows: Example: ex09-06.js - The ECMAScript For ex09-06.htm 1: var IE=document.all?true:false 2: if (!IE) document.captureEvents(Event.CLICK) 3: document.onclick=mouseClk 4: 5: var lxPos0=0 6: var lyPos0=0 7: var lxPos1=0 8: var lyPos1=0 9: 10: var iTDelta=0 11: var selectObj="char01" 12: var working =0 13: var objWidth=55 14: var objHeight=55 15: 16: function mAction() 17: { 18: if (working ==0) 19: { 20: iTDelta = iTDelta + 0.1 21: lxPos = (1-iTDelta) * lxPos0 + iTDelta * lxPos1 - objWidth 22: lyPos = (1-iTDelta) * lyPos0 + iTDelta * lyPos1 - objHeight 23: 24: if (iTDelta > 1) return true 25: 26: document.getElementById(selectObj).style.left = lxPos + "px" 27: document.getElementById(selectObj).style.top = lyPos + "px" 28: setTimeout("mAction()",10) 29: } 30: } 31: 32: function resetPic() 33: { 34: working =1 35: document.getElementById("char01").style.top = 300 + "px" 36: document.getElementById("char01").style.left = 50 + "px" 37: document.getElementById("char02").style.top = 330 + "px" 38: document.getElementById("char02").style.left = 160 + "px" 39: document.getElementById("char03").style.top = 310 + "px" 40: document.getElementById("char03").style.left = 255 + "px" 41: } 42: 43: function buttonClk(objNo) 44: { 45: working =1 46: if (objNo ==1) selectObj="char01" 47: if (objNo ==2) selectObj="char02" 48: if (objNo ==3) selectObj="char03" 49: } 50: 51: function mouseClk(e) 52: { 53: if (working ==0) 54: { 55: 56: lxPos0 = parseInt(document.getElementById(selectObj).style.left) + 57: objWidth 58: lyPos0 = parseInt(document.getElementById(selectObj).style.top) + 59: objHeight 60: 61: if (IE) { 62: lxPos1 = event.clientX 63: lyPos1 = event.clientY 64: } else { 65: lxPos1 = e.pageX 66: lyPos1 = e.pageY 67: } 68: iTDelta = -0.1 69: mAction() 70: } else { 71: working =0 72: } 73: } If any one of the first three buttons is pressed, the button click function buttonClk()is activated to select the target object. For example, if the Move e button is pressed, the function buttonClk(2) is activated and the statement in line 47 will select the "e" picture as the moving target (selectObj). The fourth button calls the function resetPic() that is defined in lines 3241 to reset the pictures to their original positions. One interesting point is that any button click (i.e., click the button using the mouse) is generally a mouse click and will trigger the general mouse click function mouseClk(). To prevent any confusion or undesirable effects from different event models (discussed later) and to guarantee the action that we want, we need to employ the variable working so that the function mouseClk()ignores the click the first time and listens to the next click event. To make this example work, the following browser detection code (see lines 13) is set to listen to the mouse click event: var IE=document.all?true:false if (!IE) document.captureEvents(Event.CLICK) document.onclick=mouseClk You've seen this structure in Chapter 6 where very little explanation was given. In fact, this is an event handler with script. The first line detects whether IE is in use. The second statement is dedicated to some older browsers such as NS4.x used to capture the click event. After that, W3C standard code is used to assign the function mouseClk() to the document.onclick handler to listen to any mouse click action on the page. You can ignore the first two statements if only W3C-compliant browsers are used. A genuine mouse click event occurring in the page will trigger the function mouseClk(). This function gets the starting position lxPos0 and lyPos0 of the selected object as shown in lines 5659. Lines 6167 are used to get the current mouse position and assign it as the end point. Also in this example, IE and NS browsers are assumed. Once you have the start and end points, you can call the mAction() function to move the object. This function uses the straight line equations
where t is a parameter that takes values from 0 to 1. The straight line starts from the point (X0,Y0) and goes to (X1,Y1). The details of the function mAction() are defined in lines 1630. In terms of programming, the straight line equation turns out to be iTDelta = iTDelta + 0.1 lxPos = (1-iTDelta) * lxPos0 + iTDelta * lxPos1 - objWidth lyPos = (1-iTDelta) * lyPos0 + iTDelta * lyPos1 - objHeight It stops drawing when the parameter iTDelta reaches 1. Otherwise, the position of the selected object is updated to the new position lxPos and lyPos and therefore makes the object move. Finally, two more variables, objWidth and objHeight, are used to locate a point inside the selected object. This point is roughly designed but will come to the tip of the mouse. Event handlers are quite useful and can be established without disturbing the page. In order to set up an event handler in this way, further understanding of the browsers and how they handle events is needed. This leads to our discussion on event models of browsers. |
Table of Contents | Previous Next |