Equalizing JavaScript Event References across IE and EOMB (Every Other Modern Browser) Part 1: DOM Level 0 Event Handlers
Far from the special form of DHTML Hell that version 4 browsers imposed on web developers in the late ’90s, today’s modern browsers are dramatically more consistent in their support for the JavaScript 1.5, CSS 1 & 2, and DOM Level 1 standards — despite the fact that IE 6 still lags EOMB (Every Other Modern Browser, as Dave Hyatt says) in literally every area.
DOM support is sufficiently consistent to facilitate nearly any common dynamic page needs without code branching. That is, except for one aspect. Arguably the most important aspect. Event Handling.
The DOM Level 2 standard is divided into several semi-independent modules that ease the job of the browser implementors by allowing them to focus on supporting one module at a time in their products. Gecko-based browsers (Mozilla, Firefox, Camino, etc.), and increasingly Opera have done an excellent job of implementing the various DOM Level 2 modules. Of the Level 2 modules, the Mozilla developers have shunned only the obscure Traversal Module. This module is arguably of little use to common web development needs anyway. Opera is not far behind, and seems to be gaining ground with several DOM 2 modules added in their Opera 7 product family. While Safari is significantly behind both groups, Apple has provided a very solid implementation of the DOM 2 basics that are needed by web authors 90% of the time.
In particular, Mozilla, Apple, and Opera have provided solid, consistent implementations of the critical DOM Level 2 Event Module. This is the portion of the DOM that allows web authors to write scripts that respond to user events (think mouse clicks and keyboard events) to create sexy, dynamic web interfaces without browser detection, branching or other unspeakable acts.
Meanwhile Internet Explorer 6 is missing one critical piece of the basic DOM puzzle… guess which module Microsoft has chosen to ignore? Yup, Events. You know, the one DOM module that enables interactive web application development in a platform-independent manner. Interactive web apps that could possibly thwart a monopolistic development platform like say… Windows. Quite a co-inky-dink, dontcha think?
So what’s a web author to do?
Today we’ll look at some nice Object-Oriented features of the JavaScript 1.5 language that can be leveraged to equalize these event handling differences in IE and EOMB. Let’s start by looking at IE and EOMB’s DOM Level 0 support…
Suppose you have the following markup fragment in your HTML interface:
<body>
<button id='my-button'>Click Me</button>
</body>
Let’s add a simple JavaScript event handler to execute on page load… nothing fancy, just an HTML 4 event handler attribute that calls a custom JavaScript function we’ll define momentarily…
<body onload='pageLoaded(event);'>
<button id='my-button'>Click Me</button>
</body>
Inline Event handling functions like this are often called DOM Level 0 event handlers. The strange ‘Level 0′ term comes from the fact that every browser had implemented this functionality before the DOM Level 1 spec (which did NOT contain this functionality) was conceived. Makes sense in a weird way.
Hey, what’s that event argument doing there? I don’t remember declaring any JavaScript variables named event. What gives?
Without getting into too many (rather confusing) details, EOMB provides an implicit argument to any DOM 0 event handlers named event that contains a reference to the current event object being handled. Meanwhile IE’s JavaScript interpreter always provides a global object reference named event that will be updated to reference the latest user-initiated event whenever one occurs.
Although this very slight difference in implementation does not make any practical difference here in DOM 0 event handlers, it can cause great confusion when moving to more sophisticated DOM features. So let’s review once:
- EOMB provides an implicit function argument named event that references the event being handled to any DOM 0 event handler.
- IE always defines a global object reference named event that is constantly updated to refer to the latest user event of any type (e.g. MouseEvent, KeyEvent, etc.). Since the object reference is global, it is also available to your DOM 0 event handlers.
So, if we want to capture a reference to the event object that represents the page load, and do something with it in our separate JavaScript function pageLoaded, we need to capture it as shown above and pass it as an argument. The variable must be spelled exactly event in DOM 0 event handlers, as that is how both EOMB and IE refer to the object. Using a variable by any other name (say, evt) will not work in a DOM 0 event handler.
In a linked JavaScript file, let’s define that pageLoaded JavaScript function…
function pageLoaded(evt) {
alert(evt);
}
As you can see, we are capturing the event reference as a variable named evt. Here, in our JavaScript code, we can name the event variable anything we want… it will still refer to the event object we passed in from our DOM 0 event handler.
Okay, so far so good. Despite the differing implementation details outlined above, using DOM 0 event handlers in IE and EOMB is identical in practice. You don’t even need to know that the implementations differ.
What’s so hard about this?
Unfortunately, beyond simple DOM 0 event handlers, the IE event model API and the DOM Level 2 Events Module API supported by EOMB begin to diverge considerably. Sadness. And understanding the difference in implementation in this simple DOM 0 example is crucial to using the more advanced event models.
That’s where we’ll pick up in part 2…