Event handling in Netscape 4

This page describes Netscape 4 only techniques.

I prepared a little example of the various event registration models, event properties and event orders. Thus you can get a quick overview of the possibilities and restrictions of event handling.

The main problem with Netscape 4 is that it is a very buggy browser. The chance of Netscape 4 crashing becomes larger with every functionality you add to the page. What this browser really needs is an onCrash event handler so you can at least say “Sorry” to your users.

If it doesn’t crash it may develop strange behavior. For instance, take the event example I prepared. In my Netscape 4's (4.74 on WinNT and Mac, 4.75 on Win98), the mouseup example works fine the first time you try it, but after that any click anywhere (and not just on the layers) causes the first sequence of events to be repeated exactly.

I tried to register the handler to click instead of mouseup. Although the bug disappeared, it turned out that the click event is only handled if you click exactly on the border of one of the layers. Lovely, truly lovely.

Finally, Netscape's official documentation (now mercifully offline) contained incorrect information. Although there are only a few instances of errors, I do not trust it any more. So be sure to always test all code you write according to the Netscape documentation and be prepared for surprises. You cannot assume it will work as advertised.

Nonetheless Netscape 4 can handle some of the simpler event handling scripts, as long as you code around its idiosyncracies.

Layers

First of all, except for very old functionality (mouseovers on links, keypress on textarea), event handlers can only be registered to layers. In this context a layer is a DIV or a similar HTML element that has position: absolute in the style sheet. For DHTML position: relative will also work, for event handling it won’t.

captureEvents()

In theory Netscape 4 requires you to tell it to start looking for the event. This is done through a special method captureEvents. The syntax is:

element.captureEvents(Event.CLICK)

Note all the upper– and lower case stuff: it is all required. Netscape 4 now actively looks for the click event. If it takes place the event handler function defined through element.onclick is executed, as in all other browsers.

To capture more than one event, do this:

element.captureEvents(Event.CLICK | Event.MOUSEOVER)

You can also release the event. If you do Netscape 4 doesn’t pay any more attention to it and nothing happens when the event takes place, even though the event handler remains registered.

element.releaseEvents(Event.CLICK)

routeEvent()

In Netscape 4, events are always captured. If you do

document.onmousedown = doSomething;
document.layers['test'].onmousedown = doSomething2;
document.captureEvents(Event.MOUSEDOWN)
document.layers['test'].captureEvents(Event.MOUSEDOWN)

and the user causes a mousedown event on test, the event is always handled by the document first. No surprises here, that’s how event capturing works.

However, without your saying so the event will never be captured by test but die a quiet death on the document level. If you want the event to also be handled by the layer, you must explicitly tell Netscape 4 to do it by using the special routeEvent() method.
Of course we use a bit of object detection to make sure the browser actually supports this method.

function doSomething(e)
{
   // called by document
   // handle the event here, then do
   if (self.routeEvent) routeEvent(e);
}

If you route the event in this way, Netscape 4 looks if any other element is interested in the event. In our example, the event is sent to test since it has an onmousedown event handler and it is the original target of the event.

Faulty documentation

So much for theory. More than two years ago I was doing some event testing and accidentally forgot the

document.captureEvents(Event.MOUSEUP)

The script ran fine in Netscape 4 nonetheless, the mouseup event was detected. When I discovered this I did some more testing and found that the click, dblclick, mousedown, mouseup, keydown, keypress and keyup events do not need the captureEvents() method when they are registered on document level. The Netscape documentation doesn’t mention this interesting fact.

The examples in the documentation always add event handlers to the window, not to the document, and it seems that the use of captureEvents() is indeed necessary for the window. Nonetheless the documentation gently led you to assume that captureEvents() is necessary on any level, window, document or layer. This is simply not true, try leaving it out and see what happens.

In my tests, the following happend:

Event Capturing Notes
Blur
Necessary Works on form elements and layers.
Not necessary On the window
Change
NecessaryWorks on form elements.
Click
Not necessary Doesn't work on Linux
Dblclick
Not necessary Doesn't work on Linux
Focus
Necessary Works on form elements and layers.
Not necessary On the window
KeyDown
Not necessary Doesn't work on Linux
Doesn't work on form elements.
KeyPress
Not necessary This is the only Key event that keeps on repeating when the user keeps the key pressed.
Doesn't work on Linux
Doesn't work on form elements.
KeyUp
Not necessary Doesn't work on Linux
Doesn't work on form elements.
MouseDown
Not necessary This is the most useful event because almost all properties that should work with all events (modifiers, which) actually work with MouseDown only. Use it instead of onClick.
MouseMove
Necessary Works when moving inside the document or layer.
MouseOut
Necessary Works when mousing out of layers, form elements, images or links inside the document or layer.
MouseOver
Necessary Works when mousing over layers, form elements, images or links inside the document or layer.
MouseUp
Not necessary

Assigning event handling functions

As an example, let's take a page that has a layer in it. In the context of event capturing, such a layer must have position: absolute in the style sheet.

----------------------------------------------------
|                                                  |
|                   document                       |
|                                                  |
|        --------------------------                |
|        |                        |                |
|        | document.layers['id']  |                |
|        |                        |                |
|        |                        |                |
|        |                        |                |
|        --------------------------                |
|                                                  |
----------------------------------------------------

Now we can define event handling functions for both the document and the layer. For instance, in case of MouseUp:

document.onmouseup = up1;
document.layers['id'].document.onmouseup = up2;

up1() is executed when a mouseUp event occurs in the document, up2() when the event occurs in the layer. So generally it's possible to assign events to either the document or a layer.

There are some differences between the events that need to be captured and those that don't need to be captured. Let's review them.

Capturing not necessary

Click, Dblclick, MouseDown, MouseUp, KeyDown, KeyPress, KeyUp.

These events do not need to be captured, although capturing them can in some cases be a good idea.

Let's continue with the example above:

document.onmouseup = up1;
document.layers['id'].document.onmouseup = up2;

If we define it like this, the document and the layer have their own, separate mouseup event, so the layer is not considered part of the document, even though an event is supposed to be captured by the highest-level structure (document, in this case) first.

A problem here: Netscape 4 on Windows and Linux do not consider text as part of the layer, while Netscape 4 on Mac does. So if you click on any text in the document or the layer, Windows and Linux ignore it while Mac uses the event handler we defined. This problem is solved by adding any captureEvent, whether on document level or on layer level.

Now if we add

document.captureEvents(Event.MOUSEUP);

the situation radically changes. Now the document is considered to 'cover up' the layer, so that when you click on the layer, the mouseup event is first sent to the general document.onmouseup and up1 is executed. Of course, if no mouseup event handler is defined for the document, nothing happens.

We can also do

document.layers['id'].document.captureEvents(Event.MOUSEUP);

Now the document and the layer still have their separate mouseup event but the text bug mentioned above is solved.

When releasing an event, the situation is more complicated. When you release the event in the document, like

document.releaseEvents(Event.MOUSEUP);

the advantages of the capturing are cancelled again. But releasing the events in the layers doesn't have any effect.

Capturing necessary

Blur, Change, Focus, MouseMove, MouseOut, MouseOver

These events have to be captured before you can assign functions to them. When they're released again, the functions are not called any more. In fact, these events behave as theory says they should behave.

To assign event handling functions to a layer only, do something like:

document.layers['id'].document.captureEvents(Event.MOUSEOVER);
document.layers['id'].document.onmouseover = function;

Most of these events don't work on every element, see the table above for details.

target in Netscape 4

The documentation pretended that the target property worked for all events on all HTML elements. Not so, in fact it rarely gives reliable information. I tested it as follows:

<DIV ID="test" STYLE="
	position: absolute;
	top: 100px;
	left: 50px;">
This is the test DIV
</DIV>

document.layers['test'].captureEvents(Event.MOUSEDOWN);
document.layers['test'].onmouseover = doIt;
document.layers['test'].onmousedown = doIt;

function doIt(e)
{
	alert(e.target.id);
}

In case of mouseover (which isn’t mentioned in the captureEvents() method, incidentally) the alert correctly gives the ID of the test layer. In case of mousedown, though, the alert gives undefined.

So target is only reliable on a mouseover or mouseout. It may, by accident, work on other events on other elements but don’t count on it. Again the documentation gives false information.

End

You have now reached the end of my Introduction to Events. Good luck in writing your own event handling scripts.