Приглашаем посетить
Грибоедов (griboedov.lit-info.ru)

9.2 Controlling objects with event handlers

Table of Contents

Previous Next

9.2 Controlling objects with event handlers

You'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 handlers

Both 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.

Table 9.1. Mouse and keyboard event handlers

Command

Description

onclick

The pointing device has been clicked

ondblclick

The pointing device has been double clicked

onmousedown

The pointing device button has just been pressed

onmouseup

The pointing device button has just been released

onmouseover

The pointing device enters the bounds of an element from outside the element

onmousemove

The pointing device was moved within the boundary of the element

onmouseout

The pointing device was moved out of the boundary of the element

onkeypress

A keyboard key is pressed and released for an element that has focus

onkeydown

A keyboard key is depressed for an element that has focus

onkeyup

A keyboard key is released for an element that has focus


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 browser window has been moved;

  • the window/object has been resized;

  • the window scroll bar position has been changed etc.

The event commands are listed in Table 9.2.

Table 9.2. Document and browser windows event handlers

Command

Description

onabort

Image downloading has been interrupted

onbeforeunload

The page is about to be unloaded from its current context

onerror

An error has occurred during the loading of external page dependencies or during the processing of a script

onload

The document or other external dependency has finished loading to the browser

onmove

The browser window has been moved

onresize

The window/object has been resized

onscroll

The window/object has been scrolled

onstop

The element's scroll bar position has been changed

onunload

The page is unloading from its current context


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).

Table 9.3. Form-related event handlers

Command

Description

onblur

The current element has lost focus (by keyboard tabbing or mouse)

onchange

The current element has lost focus (by keyboard or mouse) and the element's contents have changed

onfocus

The element has received focus

onreset

A form's Reset button has been activated

onsubmit

A form's submittal process is beginning


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 events

To 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.htm

graphics/09fig04.jpg


Figure 9.5. Key pressed

graphics/09fig05.jpg


Figure 9.7. Window scroll

graphics/09fig07.jpg


Figure 9.6. Window resize

graphics/09fig06.jpg


9.2.3 Some jumping characters

To 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

iyDelta = -35

top value

ixDelta = 20

left value


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

Y = R * cos (t)

top value

X = R * sin (t)

left value


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.htm

graphics/09fig08.jpg


Figure 9.9. Picture "W" jumps

graphics/09fig09.jpg


The next example shows how to select and drive multiple objects by using the mouse.

9.2.4 Selecting and driving objects with the mouse

Another 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.htm

graphics/09fig10.jpg


Figure 9.11. Driving objects

graphics/09fig11.jpg


The 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

X = (1 t) * X0 + t X1

Y = (1 t) * Y0 + t Y1

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