Section E. The event object and its properties


E. The event object and its properties

Warning

General browser incompatibility warning throughout this section


Once you have registered an event handler for the correct event on the correct element, you can turn your attention to the event-handling function itself. Of course the exact form of this function depends heavily on the actions you want to take. Possibilities range from a simple one-line style change to complex initializations of extra functionalities that take dozens of lines.

Sometimes you need to access the event object. The browser automatically creates this object whenever an event occurs, and it contains all kinds of useful information about the event, such as the target element, the event type, the mouse position, the key the user pressed, and much more.

The event object and its properties suffer from serious browser incompatibilities. Although many of these incompatibilities are restricted to differing property names (W3C's target vs. Microsoft's srcElement, for instance), there are areas where the problems are more fundamental, and some event properties are not present in all browsers.

The event object

Before delving deeper into its properties, you first have to access the event object, which is handled differently by the W3C and the Microsoft models:

  • In the W3C model, the event object is sent to the event-handling function as the first argument.

  • In the Microsoft model, the event object is always window.event.

Fortunately, these incompatibilities are easily accommodated by a single line of code:

// use one of these three registrations document.onclick = handleEvent; document.addEventListener('click',handleEvent,false); document.attachEvent('onclick',handleEvent); function handleEvent(e) {      var evt = e || window.event;     // do something with evt, which now     // refers to the event object } 


Note the e argument of the handleEvent() function. W3C-compliant browsers send the event object to the function as an argument. It's traditional to name the variable that holds this argument e, but of course you can use any name you like.

The first line of the function makes sure that evt contains the event object in all browsers. evt becomes e, or, if it's not available (i.e., if the browser hasn't sent an event object), it becomes window.event, the Microsoft object. We discussed the exact purpose of the || operator in 5G.

As you can see, accessing the event object is pretty easy. Unfortunately, as we'll see below, its properties contain many unpleasant surprises.

type

The type property of the event object contains the event type (mouseover, keypress, submit, and so on). Most unusually, it's supported by all browsers. In fact, it is one of the few cross-browser event-object properties.

Targeting

The event object contains various properties having to do with targeting: on which HTML element does the event take place?

The W3C properties are currentTarget, relatedTarget, and target. The Microsoft properties are fromElement, toElement, and srcElement. 7F discusses target and srcElement in depth, while 7H highlights relatedTarget, fromElement, and toElement.

Mouse position

Warning

Browser incompatibility alarm phase red


Sometimes you want to find the mouse position at the time the event took place. Poor youyou're in for a rough ride.

There are six mouse-coordinate property pairs. All have an X and a Y component, which give the mouse coordinates in pixels. All inform you that the mouse is X pixels to the right of and Y pixels below the reference point. A negative X means it's left of the reference point; a negative Y means it's above the reference point.

Of course the question is: what is this reference point? Here's where things turn sour. The reference points of the property pairs are as follows:

Pair

Reference point

Browser compatibility

clientX, clientY

The browser window

All but Safari

layerX, layerY

A Browser Wars-style layer (the nearest absolutely positioned ancestor, or, if it's not there, the document)

Mozilla and Safari

offsetX, offsetY

The event target

All but Mozilla

pageX, pageY

The document

All but Explorer

screenX, screenY

The computer screen

All browsers

x, y

Various small fry. Don't use it. There's always a better choice.

Totally incompatible; not supported in Mozilla


Let's start with the good news: screenX and screenY work in all browsers. Unfortunately, the information they contain is usually worthless: you rarely need to know the mouse position relative to the computer screenwell, maybe if you're writing a complicated drag-and-drop script.

Instead, you usually want to know the mouse position relative to the document. Often you need the coordinates because you want to place an element next to the mouse when the user mouses over a certain element. (Edit Style Sheet's color picker is an example of this.) You can use pageX and pageY to find the mouse coordinates relative to the document, add or subtract a few pixels, and transfer them to the top and left style properties of an absolutely positioned element, and you're ready for whatever comes next. This makes pageX and pageY is by far the most interesting and useful mouse coordinate property pair. But just to keep you on your toes, it's not supported by Explorer.

The second most useful pair is clientX and clientY, which gives the coordinates relative to the window (except in Safari, where they're relative to the document).

Fortunately, this pair gives us the possibility of working out the coordinates relative to the document in Explorer. If we add the scrolling offset of the page to the coordinates relative to the window, we can find the coordinates we need.

Figure 7.6. The user clicks at the point indicated by the black box. We want to know the coordinates relative to the document. pageY contains them, but is not always supported. Another way of finding the same information is to add scrollTop to clientY.


We'll discuss scrollTop fully in 9H, but this code finds the mouse position relative to the document:

var posx = 0; var posy = 0; var evt = e || window.event; if (evt.pageX || evt.pageY) {     posx = evt.pageX;     posy = evt.pageY; } else if (evt.clientX || evt.clientY) {     posx = evt.clientX +     document.documentElement.scrollLeft + document.body.scrollLeft;     posy = evt.clientY +     document.documentElement.scrollTop + document.body.scrollTop; } 


We first try pageX and pageY. If they exist, we take their values and can move on. If they don't exist, we use clientX and clientY, add the scrollLeft and scrollTop of both document.documentElement and document.body, and we've found the same value.

layerX/Y and offsetX/Y are not supported by all browsers. They are useful only when you want to find an element's position relative to its absolutely positioned parent:

var x = [the element]; var pos = x.layerX || x.offsetX; // now pos holds the horizontal position of x relative to its // absolutely positioned parent. 


Note that this only works if the absolutely positioned element is the direct parent of x. If it isn't, odd side effects may occur.

Don't do it

The chaos surrounding the mouse position is the most severe Browser War-style incompatibility still in existence, which makes the position properties rather hard to use.

Besides, any script that uses the mouse position is fundamentally inaccessible: when the user doesn't use a mouse, the mouse coordinates don't hold useful information. In fact, you might find wildly incorrect mouse coordinates because, for instance, the mouse pointer is permanently located in the middle of the computer screen.

Fortunately, finding mouse coordinates is rarely necessary, as Edit Style Sheet's color picker proves. The idea of the script is that the user clicks on the Pick color link, and that the color picker then appears at the same height as the link.

Figure 7.7. Clicking on the Pick color link opens the color picker at the same height as the link.


This script needs to calculate the color picker's position. This calculation could start from the mouse position ("place the color picker 200 pixels to the left of and at the same height as the current mouse position"), but a far better technique is to start from the position of the link itself ("place the color picker 200 pixels to the left of and at the same height as the link the user clicked on"). We'll discuss this in 9H.

As an added bonus, the position-finding script is accessible: it also works for non-mouse events such as focus.

90% of the scripts that calculate the mouse position could just as easily use the position of the element the user clicked on or moused over for their calculations. Therefore, my advice is not to try to find the mouse position at all. You rarely need it.

Mouse button

Warning

Browser incompatibility alarm phase orange


It's also possible to read out the mouse button the user has clicked on. You can find this information in the button property. 99.9% of the mouse-button checks are about disabling the right mouse button (return false!) so that the user can't use View Source. You can use the button property to do this: if the user presses the right mouse button to bring up the context menu, button is 2.

That's the good news. The bad news is that W3C's specification for button is flat-out wrong, although many browsers have implemented it regardless. Microsoft uses a proprietary system that's much better than the standard.

Model

Left button

Middle button

Right button

W3C

0

1

2

Microsoft

1

4

2


What's wrong with W3C's system? The 0. First of all, using the value 0 to indicate that something has happened is very odd. In my opinion, 0 should mean "no button pressed."

The Microsoft system is a bitmask, which allows you to detect several buttons at once. For instance, when the user presses the left and right buttons simultaneously, button becomes 1 + 2 = 3; when he presses the right and middle buttons, it becomes 2+ 4 = 6.

W3C-compatible browsers don't support this bitmask. Worse: they cannot support it, because of the 0. Left + right buttons would become 0 + 2 = 2, the same as when the user clicks the right button only.

I hope that a future version of the specification will use the Microsoft values, since they make sense. Fortunately, this difference doesn't matter in practice, since you want to detect a right click in order to disable the View Source option. As I said, on a right click, button is 2 in all browsers.

Key properties

Sometimes you want to know which key the user has pressed. As we saw in 7B, this is only possible on the keydown and keyup events. Some browsers don't allow it on the keypress event.

keyCode contains the code of the pressed key. The letters range from 65 (a) to 90 (z), and most other keys have their own code, too.

The altKey, ctrlKey, and shiftKey properties are true when the user presses the Alt, Control, or Shift key, false when he doesn't. In some browsers, these properties are available only when the user presses a "real" key simultaneously.



ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 116

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net