events.js

Practical uses

Cross-browser event handler assignment, mouse movement tracking

Version requirement

JavaScript 1.2

Functions

enableEffects(), showXY(), keepKeys(), showKeys()

If you haven’t experimented with cross-browser event handling scripts, this might be just the primer for you. This example utilizes three event handlers: onclick, onmousemove, and onkeypress. When you first click anywhere in the document space, the JavaScript captures the initial x and y coordinates of the mouse-pointer arrow with respect to the browser window. After that, the status bar displays the x and y coordinates as the user moves the pointer arrow around. Clicking once again “turns off” the coordinate tracking and calculates the pixel distance between the point the user first clicked and current location. You can see this in Figure 6.7 and Figure 6.8.

x and y mouse coordinates in the status bar

Figure 6-7. x and y mouse coordinates in the status bar

The pixel distance between the two points

Figure 6-8. The pixel distance between the two points

Independent of the mouse action, you can also type any sequence of keys on your keyboard. The status bar will then display each of the individual keys you type. When you finish, choose the “Show Keys” button, and you’ll get a JavaScript alert dialog box that displays the cumulative sequence of keys you entered up to that point. Figure 6.9 shows this. Choose “OK,” and you start again from scratch.

These are the keys the user typed

Figure 6-9. These are the keys the user typed

By now you’re familiar with the intricacies of coding cross-browser stylesheets. You know: LAYER tags in one browser, DIV tags in the other.[3] Things don’t change much for the good when it comes to the event models, either. If you check the source code in events.html,you’ll find the following two lines of JavaScript:

document.onclick = enableEffects;
document.onkeypress = keepKeys;

The onclick event handler is associated with function enableEffects(), and the onkeypress event handler is associated with function keepKeys(). Both functions are shown below. Notice that neither function has any parentheses in the syntax. That is, the code does not look like this:

document.onclick = enableEffects();
document.onkeypress = keepKeys();

Using parentheses would call each method the moment each line was interpreted. You don’t want that: the event handlers are associated by a reference to the functions, instead. Look at the code in Example 6.5.

Example 6-5. events.js

     1  var keys = '';
     2  var change = true;
     3  var x1, x2, y1, y2;
     4  
     5  function enableEffects(ev) {
     6    if(change) { 
     7      if(document.layers) {
     8        x1 = ev.screenX;
     9        y1 = ev.screenY;
    10        document.captureEvents(Event.MOUSEMOVE);  
    11        }
    12      else { 
    13        x1 = event.screenX;
    14        y1 = event.screenY;
    15        }
    16      document.onmousemove = showXY;
    17      }
    18    else { 
    19      if (document.layers) { 
    20        x2 = ev.screenX;
    21        y2 = ev.screenY;      
    22        document.releaseEvents(Event.MOUSEMOVE); 
    23        }
    24      else { 
    25        x2 = event.screenX;
    26        y2 = event.screenY;
    27        document.onmousemove = null; 
    28        }
    29      window.status = 'Start: (' + x1 + ',' + y1 + 
    30        ')  End: (' + x2 + ',' + y2 + ')  Distance: ' + 
    31        (Math.round (Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 
2)))) + ' pixels';
    32      }
    33    change = !change;
    34    }
    35  
    36  function showKeys() {
    37    if (keys != '') { 
    38      alert('You have typed: ' + keys);
    39      window.status = keys = ''; 
    40      }
    41    else { alert('You have to type some keys first.'), }
    42    }
    43  
    44  function showXY(ev) {
    45    if (document.all) { ev = event; } 
    46    window.status = 'X: ' + ev.screenX + ' Y: ' + ev.screenY;
    47    }
    48  
    49  function keepKeys(ev) {
    50    if (document.layers) { 
    51      keys += String.fromCharCode(ev.which); 
    52      window.status = 'Key pressed: ' + String.fromCharCode(ev.which);
    53      } 
    54    else { 
    55      keys += String.fromCharCode(event.keyCode); 
    56      window.status = 'Key pressed: ' + String.fromCharCode(event.keyCode);    
    57      }
    58    }

Function enableEffects() is the epicenter for the clickand mouseoverevents. I call your attention to lines 6, 18, and 33:

if (change) { ....

else { ....

change = !change;

The variable change starts as true and is changed to its opposite (i.e., to false, back to true, and so forth) during every call. Since clicking calls enableEffects() and change is true the first time, that brings lines 7-15, shown here, into effect:

if(document.layers) {
  x1 = ev.screenX;
  y1 = ev.screenY;
  document.captureEvents(Event.MOUSEMOVE);
  }
else {
  x1 = event.screenX;
  y1 = event.screenY;
  }

These lines capture x and y coordinates and enable the onmousemove event handler. If document.layers exists, the user has Navigator. The event object created on the fly is reflected in the argument passed to the function, named ev in this case. Global variables x1 and y1 are set to the respective x and y coordinates where the user first clicks (contained in screenX and screenY ). Then the call to the document method captureEvents() causes the mousemoveevent to be intercepted.[4]

If document.layers does not exist, the script assumes the user has Internet Explorer and takes appropriate actions to do the same as above. Microsoft’s event model, however, defines an event object as event. That’s where properties screenX and screenY will be waiting. No additional method calls are required for event capturing in MSIE, which leads us to line 16:

document.onmousemove = showXY;

The onmousemove event handler is then assigned by reference to function showXY() in both browsers. Let’s have a quick look at showXY():

function showXY(ev) {
  if (document.all) { ev = event; }
  window.status = 'X: ' + ev.screenX + ' Y: ' + ev.screenY;
  }

The call to showXY() each time the mouse moves displays the x and y coordinates of the mouse-pointer arrow. The x and y values are referenced in the same cross-browser manner as before. showXY() is called repeatedly as the user moves the mouse around. This happens until the user decides to click again, which puts in another call to enableEffects(). However, variable change is false this time around, so lines 19-31 get the call:

if (document.layers) {
  x2 = ev.screenX;
  y2 = ev.screenY;
  document.releaseEvents(Event.MOUSEMOVE);
  }
else {
  x2 = event.screenX;
  y2 = event.screenY;
  document.onmousemove = null;
  }
window.status = 'Start: (' + x1 + ',' + y1 +
  ')  End: (' + x2 + ',' + y2 + ')  Distance: ' +
  Math.round(Math.sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)))
     + ' pixels';

Variables x1 and y1 hold the values of the starting click location. Now variables x2 and y2 are set to the values of the stopping click location. There is no longer a need to keep processing the onmousemove event handler. So with Navigator, the releaseEvents() method is called to cease interception of the mousemove event. The same result is performed by setting document.onmousemove equal to null in MSIE.

All that remains is to display the distance between the starting and stopping points. Do you recall the distance formula? You may have used it in ninth grade Geometry class. That’s the same formula here in lines 29-31.

That takes care of the onclick and onmouseover event handlers, leaving only onkeypress. Remember that document.onkeypress was set to call function keepKeys() during the loading of events.html. Here is keepKeys(), lines 49-58:

function keepKeys(ev) {
  if (document.layers) {
     keys += String.fromCharCode(ev.which);
     window.status = 'Key pressed: ' + String.fromCharCode(ev.which);
     }
   else {
     keys += String.fromCharCode(event.keyCode);
     window.status = 'Key pressed: ' + String.fromCharCode(event.keyCode);
     }
  }

Using the same browser detection technique, empty string variable keys is set to itself plus the string equivalent of the key pressed. This happens with String.fromCharCode() , regardless of browser. JavaScript 1.2, however, represents the keystrokes as ISO Latin-1 characters. JScript uses Unicode representations. The number in JavaScript is stored in the which property of the event object. The number for JScript is reflected in the event.keyCode property. So the user types a number of keys, then selects the “Show Keys” button. This function alerts the value of keys, then sets it to an empty string.



[3] Actually, you can use DIV tags for positioning in Netscape Navigator 4.x as long as you include a value for “position” in the STYLE attribute. However, until Netscape comes on board with the document object model, using the LAYER tag gives you access to all the properties of the Layer object.

[4] At least some versions of NN4.x seem to respond only intermittently to the mouse clicks. That is, sometimes you have to click twice to start or stop the tracking. I haven’t found any supporting documentation about such a bug.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.111.1