A. Event handling in Javascript 1.2 (Netscape)
We know that the original method of handling an event was to say
something like:
<body onLoad="Dosomething();" >
where the user-defined function Dosomething() is invoked when the
web-page body has finished loading. We also know that one can put in
several such statements separated by semicolons, and that returning
false cancels any further action in for example an anchor.
All of this still applies in JavaScript 1.2, but there is a lot more.
Note that there are three reasons why you should avoid this new
functionality:
- It's not backward compatible with older browsers;
- You have to account for differences in Navigator and IE;
- It can be confusing.
Conversely, the new approach often confers abilities that are
sorely lacking in older versions! You have to balance the risks and
the benefits.
What is the new approach?
The new approach is simply to say:
object.eventhandler = function
here, you specify the name of the event-handling function
without
any following parenthesis. One might for example say:
window.onload = Dosomething;
There is a significant irritating requirement here - despite the
event being onLoad, for compatibility with Navigator 3.0, the whole darn
thing must be written as onload - that is, all in lower case!
The same applies to all event handlers - write the silly things as lowercase
(You might look through the preceding six pages and see how often we've
erred in this regard. Gosh)!
There's another major catch - it's all very well to dynamically allocate
a function to, for example, a button or anchor, but beware - the button
(or whatever) must have been defined before you allocate the function to
it. For example, if you say
document.forms[0].button[0].onclick = fred;
in JavaScript in the head of a document, this will fail as silly
old JavaScript will try and run the code before it's created the button.
A solution is obvious - only run the allocation when the body of the
document has loaded, using onLoad.
Capturing Events using captureEvents
The method captureEvents() adds further power.
In version 1.2, this method, as well as releaseEvents() are
defined for windows, layers and documents. They allow you to intercept
events before they get to their destination!
You can specify a variety of events that can be captured, for example:
- Event.CLICK
- Event.MOUSEDOWN
- Event.MOUSEUP
Note that here, for reasons best known to Netscape, the events are
spelled in UPPERCASE! Every event to be captured must be preceded by
Event. An added frill is that multiple events can be specified,
thus:
window.captureEvents(Event.CLICK | Event.MOUSEDOWN)
and so on.. Separate the events with | pipes |
You don't have to release all the events you are capturing at the
same time. You might for example say the above, and then later:
window.releaseEvents(Event.CLICK)
leaving Event.MOUSEDOWN to carry being captured!
Once you've specified the event to capture, you still have to
specify a function that does the actual capture! This is a major
clumsiness, but all you do is you use the now-familiar new approach, for example:
window.onclick = whatever;
Event Capture in detail
Once one has captured an event, how does the event handling function
deal with it? We've already covered this in part four of our tutorial, but
to recap:
JavaScript passes an event to the function.
In JavaScript 1.2, every event is also an object!
We say for example:
function Dosomething (ev) { /* function definition goes here */ }
and then can talk within the function about the properties of the
event ev passed to it. As expected, we can return false from
a event-handling function to prevent further processing, or true to
allow normal handling to continue.
Note that you can also talk about an event object from within a tag,
for example you could say:
<a href="whatever.htm" onClick="alert('Hi you did a ' + event.type)" >
where the special object reference event allows you to
refer to the properties of the click event. (We will later describe all the
properties associated with all the events in JavaScript 1.2)
The handleEvent() method
This is a cute wrinkle - you can use it to force a particular object to
handle an event. For example, in the above our handler Dosomething
might pass control to a particular link thus:
document.links[0].handleEvent(ev);
.. where we have previously set up an event handler for the link
referred to!
NOTE that if you refer an event to another handler, that handler cannot
directly cancel the event. Only the first recipient of an event can cancel it!
However, this is easily sorted out - you can pass information back up the
chain to the original recipient. Say:
outcome = document.links[0].handleEvent(ev);
within the first handler, and then return the value of outcome
from the first handler, to either cancel or not cancel the event!
handleEvent cannot be used in layers.
routeEvent()
[look this up]
All the events
Here is a list of events for JavaScript 1.2 (Navigator):
All the events for 1.2
|
Event |
Meaning |
Discussed below in.. |
keydown
| key is depressed
| Section 1
|
keypress
| key press (including repeats)
|
keyup
| key release
|
click
| click on an item (Note that in Navigator, but not IE,
the Backspace key generates a click event!)
|
dblclick
| doubleclick (avoid this)
|
mousedown
| mouse button is depressed
|
mousemove
| mouse is moved
|
mouseup
| mouse button is released
|
mouseover
| mouse cursor moved over something
|
mouseout
| mouse cursor leaves something (was over)
|
dragdrop
| a system file (or other item) is dragged and dropped onto a window
|
blur
| item loses focus for key input
| Section 2
|
focus
| item gains focus
|
change
| contents of a box change
|
error
| a loading/JavaScript error occurs
| Section 3
|
load
| an image or document finishes loading
| Section 4
|
unload
| an image or document is killed
|
move
| a window is moved
| Section 5
|
resize
| a window or frame is resized
|
We will examine the lot in the following sections.
1. Keypress and Mouse Events
These events can only be trapped in JavaScript 1.2; NOT in earlier versions.
Trapping a keypress
When a key is pressed, there are 3 events generated. The corresponding
handlers, in order, are:
- onKeyDown
- onKeyPress
- onKeyUp
They are all similar. We'll use onKeyDown as a prototype:
onKeyDown
This applies to: document, Image, Link, Text and Textarea objects
Javascript passes the event handler an object with the properties:
- target = the original object target
- type = "keydown" (always)
- layerX = horizontal pixel position of mouse in layer at time of event
- layerY = similar, but Y position
- pageX, pageY = similar, but in relation to the document
- screenX, screenY = also similar, but in relation to screen!
- which = the ASCII value of the key pressed
- modifiers = bit image of modifying keys pressed at the same
time (Shift, Ctrl, Alt, and Meta).
To cancel the key event, the event handler should return false.
One could for example "re-route" typed input from a text box to elsewhere
by capturing the keypress event and then using it elsewhere.
The modifiers |
How do we check the modifiers to see which key was pressed? We perform
a logical AND between the number contained in the modifiers, and
a mask value. In other words, a single bit is set for each of
the keys, and we mask out all the other bits, leaving a value of
zero if the flag isn't set, or non-zero if it is. The possible mask
values we can use are:
- Event.ALT_MASK
- Event.CONTROL_MASK
- Event.SHIFT_MASK
- Event.META_MASK
We might say something like:
if (ev.modifiers & Event.ALT_MASK)
{ /* do something */ };
which would do something if the Alt key was depressed when the
event occurred.
|
onKeyPress and onKeyUp
These are similar to onKeyDown. Holding a key down for some time (how long?) will
result in repeated keypress events, which you can intercept.
You could also for example record the time when a key is released by
recording the Date() in a handler for onKeyUp.
Trapping a click on an item
We have already provided an example in part four.
Here we flesh things out.
onClick
This event occurs with document, Button, Checkbox, Link,
Radio, Reset and Submit objects. The onClick event can be detected
in JavaScript 1.0, but the event handler only works in 1.2 and above.
The event object passed to the handler has the following properties:
- target, layerX, layerY, pageX, pageY, screenX, screenY
and modifiers are as for a key event;
- type = "click" (always)
- which = 1 for a left mouse click, 3 for a right click;
Note that if you click on a button, the coordinates returned are
(0,0). As usual, if the handler returns false, then the action
invoked by the click is cancelled.
Mouse Clicks: onMouseDown, -Move, -Over, -Out and onMouseUp
These events are only captured in JavaScript 1.2 and above.
They are very similar to the click event described above. Note that
the onMouseDown and onMouseUp events precede the onClick event!
If the onMouseDown event is cancelled (returns false) then NO click
event will be generated. There is also an onDblClick event and an
onDragDrop, the meanings of which are obvious.
onDblClick works with Button, Checkbox, document, FileUpload,
Link, Password, Radio, Reset, Select, and Submit objects. It doesn't
work on Macs!
onDragDrop is a specific event associated with windows,
invoked by ondragdrop, self.ondragdrop, or window.ondragdrop (Hooray
for redundancy). It's used to drag a file onto a window - the
browser's default is to load the file (except with FTP). Note that
dragdrop implies that the system's drag and drop mechanism has
been invoked - the thing dragged and dropped onto the navigator
window is a system item.
You can also use windowname.ondragdrop, where windowname
is the name of the window object. The object associated with onDragDrop
has the properties type (unsurprisingly, equal to "dragdrop"), target, and data.
The data property is an array of strings containing the URLs of the
dropped objects! There are lots of security constraints governing whether
you can actually read the .data property! (You need a signed script with
'UniversalBrowserRead' privileges).
If one traps the onMouseDown event, then
one can override the normal response to a right click and turn off
the pop-up menu that usually results. The type attribute of the object
provided for all of these reflects what event was trapped e.g. "mousemove".
Note that by default mouse movements are not passed
to objects. You have to first specify:
captureEvents()
We already know that objects that can invoke captureEvents() are windows, documents
and Layers. Take care - a vast number of events will be generated by
a single mouse movement. An example of a layer
tracking a mouse movement is:
Moving a frame with the mouse (Netscape 4.x)
(from databynet.com)
|
function trackMouse(ev)
{ myLayer.pageX = ev.pageX
myLayer.pageY = ev.pageY
}
document.captureEvents(Event.MOUSEMOVE)
document.onmousemove = trackMouse
|