Section B. The events


B. The events

During the preparation of your scripts, you have to decide which events to use. In this section we'll discuss all common events, and in 7G we'll take a look at the events I chose for the example scripts.

The events can be divided into three groups:

  • Mouse events, caused by a certain mouse action.

  • Keyboard events, caused by a certain key action.

  • Interface events, which fire when something happens to the page, for instance, when a form is submitted or the page unloads.

Terminology Clarification

If the user clicks on a link, a click event takes place. If you want a script to run when that click event takes place, you register an onclick event handler.


Mouse events

The common mouse events are click, dblclick, mousedown, mousemove, mouseout, mouseover, and mouseup. They are available on all HTML elements. In addition, we'll discuss the Microsoft proprietary mouseenter and mouseleave events.

Mouseover and mouseout

When the user moves the mouse over an element, a mouseover event fires. When the user moves the mouse out of an element, a mouseout event fires.

Note that the mouse may move over and out of a lot of elements in a short time, especially when many elements have a visible (i.e., mouse-overable) part. The mouseout event, especially, can turn nasty in such environments. We'll discuss these problems in more detail in 7H, but the basic rule is to always carefully check the target of your mouseover and mouseout events before doing something.

Figure 7.1. If you move the mouse on the path the arrow shows, the example on the left triggers one mouseover event for each of the three links. But the example on the right has an extra padding on the <li>, so following the same path triggers nine mouseover events (three for the links and six for the <li>s above and below each link). If your script doesn't expect mouseovers on <li>s, you have a problem.


Mousedown and mouseup

The mousedown event occurs when the user depresses the mouse button. The mouseup event occurs when the user releases the mouse button. They are very popular in drag-and-drop scripts (mousedown: user selects item, mousemove: user moves item, mouseup: user releases item), but otherwise you'll rarely need them.

Click

A click event occurs when one element receives a mousedown event followed by a mouseup event. It is by far the most common of the mouse events.

The click event also fires when the user has focused on an element and then presses Enter. Therefore, it is the only accessible mouse event.

On elements such as links and buttons, you can think of click as an activate event: the user activates a link or button, and it doesn't matter whether she uses a mouse click or a keystroke to do so.

Dblclick

The dblclick (double click) event occurs when one element receives two click events in rapid succession. In practice, you cannot use a click and a dblclick event on the same elementit's impossible to teach all browsers to distinguish between the two.

Mousemove

The mousemove event occurs when the user moves the mouse. In theory, every movement of 1 pixel counts as a mousemove event, so this event is likely to be fired many times over during even the smallest mouse movement.

This event is mostly used in drag-and-drop scripts.

Mouseenter and mouseleave

Two Microsoft proprietary mouse events are interesting enough to discuss, even though they're supported only by Explorer.

The mouseenter and mouseleave events are similar to mouseover and mouseout, but with an important difference. Mouseover and mouseout events fire when a user mouses over or out of the element on which they're defined, or one of its descendant elements. In contrast, mouseenter and mouseleave fire only when the user mouses over or out of the element on which they're defined, and ignore any events on its descendants.

Take this example:

<p >This is a <em>test</em> paragraph.</p> document.getElementById('test').onmouseover = handleEvent; 


When the user mouses over the paragraph, handleEvent() is executed. When she mouses over the <em> that's a child of the paragraph, handleEvent() is also executed, since the mouseover event bubbles up to the paragraph. (We'll discuss event bubbling in 7D.)

If we use mouseenter, the situation changes:

document.getElementById('test').onmouseenter = handleEvent; 


Now handleEvent() is still executed when the user mouses over the paragraph, but nothing happens when she mouses over the <em>, since the event did not take place on the element on which the onmouseenter event handler is defined.

Mouseenter and mouseleave are therefore the true JavaScript equivalents of the CSS pseudo-class :hover. In addition, they're far easier to work with than mouseover and mouseout, especially in complicated dropdown/DHTML menus. I still have a secret hope that other browsers besides Explorer will start to support them.

Meanwhile, if you happen to work on an Explorer-only site, use mouseenter and mouseleave and forget about mouseover and mouseout. It'll save you a lot of headaches.

Accessible mouse events

Mouse events have a serious accessibility problem: except for the click event, they don't fire when the user doesn't use a mouse. If the user goes from link to link by keystrokes, no mouseover event will fire, since the mouse pointer is not placed over the elements.

Therefore, any script that relies exclusively on mouse events is inaccessible to keyboard users. The solution to this problem is, obviously, to use other events in addition to the mouse events.

Adequate non-mouse emulation events exist only for mouseover and mouseout. When the user tabs to links or form fields, these elements gain the focus, and when the user tabs away from them, the elements are blurred. Therefore, the non-mouse equivalents of mouseover and mouseout are focus and blur. We'll discuss these events later.

The other mouse events are harder to emulate. If you wish, you can think of keydown and keyup as the equivalents of mousedown and mouseup, but be warned that these events are not the same, and that the equivalence is strained at best. For instance, the keyboard events fire when the user presses any key, while a perfect mousedown/up simulation requires these events to fire only when the user presses the Enter key.

The mousemove events cannot be emulated at all. If your script hinges on a mousemove event, you might add an extra script module that allows keyboard users to move an element by keystrokes.

Keyboard events

The keyboard events are keydown, keypress, and keyup. Generally they are available on all text-accepting HTML elements such as form fields, as well as on links, forms, and the document.

Keyup is the simplest of the three: it fires once when the user releases a key. Note that it fires after the character has been added to the form field.

Keydown and keypress fire continuously as long as the user keeps a key depressed. (Their frequency depends on the keyboard repeat rate the user has chosen in his computer settings.)

Warning

Browser incompatibilities ahead


If the user presses a key to enter text in a form field, the keydown and keypress events fire before the character has been added to the form field. Therefore, if you want to prevent the character from being added, you must use keydown or keypress. To make matters more complicated, Mozilla allows this prevention only on keypress, not on keydown.

Unfortunately, keypress is the most useless of the keyboard events, and you should generally steer clear of it. For instance, keypress does not always contain information about the actual key the user has pressed, and in some browsers doesn't fire at all if the user presses a key combination, such as Ctrl+C.

If you need a cross-browser script that detects the key the user has pressed and also prevents the character from being added to a form field, you have a problem. Detecting the key requires keydown or keyup, while preventing the character from showing up requires keypress. At the time of writing I don't have a solution.

Fortunately, you rarely need these two functionalities in the same script. All example scripts that use keyboard events just read out the text the user has typed. They don't need to know which key was pressed (that information is part of the text, anyway), and they don't want to prevent the user from typing more characters, either.

Interface events

Warning

Browser incompatibilities ahead


Interface events are indirect events: they take place after the user has performed a certain mouse or key action with "special meaning." For instance, if the user clicks a Submit button, a click event fires on the button. Afterwards, the submit interface event takes place, since a click on a Submit button has the special meaning "submit form."

The common interface events are blur, focus, change, contextmenu, load, unload, readystatechange, reset, submit, resize, and scroll. Their availability varies, as noted in their descriptions.

blur and focus

The focus event fires when an element gains the focus, for instance, because the user clicks on it or tabs to it. The blur event fires when an element loses the focus. These events are available on form fields, links, and the window.

These events serve as keyboard-accessible equivalents of mouseover and mouseout.

No form Validation for Onblur or Onchange

Users often use tabbing to quickly navigate through a form so you might consider using the blur event for form validation (to validate a form field as soon as the user is done with it, i.e., when the field becomes blurred).

Don't do thisit's extremely annoying. The user generally doesn't want to be disturbed when he's busy filling out a form.

You could use the change event instead (and validate when the user has changed the content of a form field). It is somewhat less annoying than blur because it doesn't fire when the user enters nothing in a field.

Even so, I advise you to use onsubmit for all your form validation scripts. That's what the user expects, after all. First enter all data, and then validate all data.


change

The change event fires when the user has changed the value of a form field. On select boxes, the event fires as soon as the user selects anything; on checkboxes and radio buttons, the event fires when the user checks or unchecks them. On text fields, the event fires when the field loses the focus after the user has changed its content.

The change event is not available on HTML elements other than form fields.

The change event's behavior on select boxes can have accessibility consequences. When you use the arrow keys to go through a list of options, the change event will fire for every option you encounter, even though it should only fire when you've reached the option of your choice.

Therefore it's best to use a separate Go button next to the select box. The user selects an option by mouse or by keyboard, and then uses this button to activate that option.

Explorer Problem

In Explorer, the change event on checkboxes and radio buttons fires when the field is blurred, not when the user checks or unchecks it. This matters when your interface needs to respond immediately to user actions, as Usable Forms does. In those cases, you might consider using the click event instead.

To see the problem, try Edit Style Sheet's checkboxes in Explorer.


contextmenu

The contextmenu eventoriginally a Microsoft invention but currently supported by most browsersfires when the user calls up the context menu, usually by right-clicking on the page. This event is typically used to disable the context menu so that users cannot choose the View Source command.

load and unload

The load event fires when the page has been loaded completely, including all external files such as images. We discussed this event in detail in 4E.

The unload event fires when the page unloads for whatever reason. It is not possible to distinguish between the various ways of unloading a page, i.e., clicking on a link, submitting a form, or closing the browser window. Neither is it possible to cancel the unloading of the page.

Both events are available on the window object. In addition, the load event works on images. When the image has been loaded completely, its load event fires.

readystatechange

The readystatechange eventoriginally a Microsoft extension but now supported by all browsersis important when you use XMLHttpRequest, but rarely used outside such a context. We'll discuss this event in more detail in 10A.

In Explorer, the event applies to all elements, but the other browsers support it only on an XMLHttpRequest object.

Opera Load/Unload Problem

The load and unload events are unreliable in Opera: they do not fire when the user loads and unloads pages by means of the Back and Forward buttons or their equivalent keystrokes.

A victim of this odd behavior is Site Survey. This script works with the unload event, but since it cannot be certain to catch every unload event in Opera, the script will never be guaranteed to work correctly.

At the time of writing there is no solution to this problem.


reset and submit

The reset and submit events fire when the user resets or submits a form. onreset event handlers are very rare, but most form-validation scripts use the submit event to fire the validation functions. Both events are available only on forms.

Note that the submit event does not fire if JavaScripts submits the form, only when the user does.

   document.forms[0].onsubmit = handleEvent;  document.forms[0].submit();  // event does not fire, so handleEvent is not executed. 


Haslayout

The hasLayout property has profound consequences for all kinds of CSS-related actions in Explorer. Discussing this property in full falls outside the scope of this book; you can read an introduction to the property and the problems it causes at http://www.satzansatz.de/cssd/onhavinglayout.html.


Minor Resize Problems

Mozilla fires the event once when the user stops resizing the window. Explorer and Safari fire it continuously as long as the user is busy resizing the window. Opera fires it a lot of times, but only when the user has stopped the resizing.

This may matter if you write long and involved onresize event handlers.


resize

The resize event fires when the user resizes the browser window, and therefore it is generally only available on the window. (In Explorer the event is available for all elements that "have layout.")

scroll

The scroll event fires when the user scrolls something. It does not matter whether the user drags the scrollbar, uses the arrow keys, or the mouse wheel. The scroll event is available on any element that has a scrollbar.

W3C events

W3C has defined a lot of potentially useful DOM events. The most general one is DOMSubTreeModified, which fires whenever any change occurs in the DOM tree below the element on which it's registered. Unfortunately, at the time of writing, this event is supported only by Mozilla, and even in that browser it doesn't work flawlessly.

DOM Events

Study the DOM events at http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-eventgroupings-mutationevents. As soon as their browser support becomes decent we'll use them a lot, since some of them are very handy.


Microsoft Events

Study the MS events at http://msdn.microsoft.com/workshop/author/dhtml/reference/events.asp. Obviously, most of them work only in Explorer.


Microsoft events

Microsoft has also defined a lot of events, some of which could be useful. The most important ones are the mouseenter and mouseleave events discussed several pages back.

The default action

Many events have an associated default action. For instance, clicking on a link means the browser should load the page the link points to. Submitting a form means the browser should send the form to the server. Pressing a key means the browser should add the character to the text field the user is working on.

The general rule is that the event handler is executed first, and the default action takes place afterwards. This allows the event handler to cancel the default action.

Occasionally the purpose of an event handler is to find out whether the default action should take place or not. Form Validation is the most obvious example: it exists to decide whether the form submission started by the user should be allowed, or whether it should be aborted because the user has made a mistake.

Exception: Unload

The default action of the unload event (unload the page) is a special case: it cannot be cancelled. If it could be cancelled, you could prevent a user from leaving your site, and that's obviously undesirable.


The return value of an event-handling function serves to allow or disallow the default action. If the function returns false, then the default action is cancelled. Any other return value will cause the default action to take place.

Take this simple example:

var x = document.getElementsByTagName('a'); for (var i=0;i<x.length;i++) {     x[i].onclick = askConfirmation; } function askConfirmation() {     return confirm('Are you sure you want to follow this link?'); } 


We define an onclick event handler for all links in the document. The default action of a click event on a link is loading the page defined in the href property of the link.

However, before that happens, the click event takes place, askConfirmation() runs, and a confirm box (see 6E) is shown. The user can click OK (true) or Cancel (false). This boolean value is returned to the event handler by askConfirmation(), and it indicates whether the default action should take place (true) or not (false).

Form Validation contains a real-world example:

[Form Validation, lines 73-106, condensed heavily]

function validate() {    var validForm = true;    if (error found)           validForm = false;    return validForm; } 


The validate() function is the event handler of the submit event. It uses a variable validForm that's initially true, but becomes false when the script finds an error. It is returned at the end of the function. Thus the default action of the submit event (submit form) is cancelled when the function finds a mistake in the form.

As we'll see in 7F, event handlers can become methods of the object you register them onprovided you register them correctly. return false works only from a function that is directly assigned as a method of an HTML element.

return false works in this case:

var x = document.getElementsByTagName('a'); for (var i=0;i<x.length;i++) {     x[i].onclick = askConfirmation; } 


This, however, does not work:

var x = document.getElementsByTagName('a'); for (var i=0;i<x.length;i++) {     x[i].onclick = function () {                           askConfirmation();     } } 


Now the onclick method of the link calls askConfirmation(), and although the function still returns true or false, this return value is not caught, and disappears without a trace.

A return false in an event handler works in the following cases:

x.onclick = askConfirmation; x.addEventListener('click', askConfirmation,false); x.attachEvent('onclick', askConfirmation); 


It does not work in the following cases:

<element onclick="askConfirmation()"> x.onclick = function () {     askConfirmation(); } x.addEventListener('click', function () {     askConfirmation(); },false); 


An extra return statement will suffice to get these last examples in line:

<element onclick="return askConfirmation()"> x.onclick = function () {     return askConfirmation(); } x.addEventListener('click', function () {     return askConfirmation(); },false); 


W3C and Microsoft models

The W3C and Microsoft models also define ways to cancel the default action. In the W3C model, you have to call the preventDefault() method of the event object, while the Microsoft model requires you to set its returnValue property to false.

var evt = [the event object]; if (evt.preventDefault)     evt.preventDefault(); evt.returnValue = false; 


I never use such a construct, since return false is far simpler and completely cross-browser.

Event simulation

There are a few event-simulation methods you should know about. These methods simulate the occurrence of an event, and that can sometimes be useful.

  • In 6D we encountered the focus() and blur() methods of the window. They also work on form fields, and, unsurprisingly, they set or remove the focus on the form field you use them on.

  • The click() method allows you to simulate a click on a form field. If, for instance, you use it on a checkbox, it changes from checked to unchecked or vice versa, just as if the user had really clicked on it. There's one exception: you cannot use the click() method on a file upload field in Mozilla or Opera.

  • The submit() and reset() methods of a form submit or reset the form. Note that when you use the submit() method, the onsubmit event handler of the form will not fire.



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