Updated: 2001-04-12: Fixed bugs in fromElement and toElement
Updated: 2001-03-13: Added support for offsetX and offsetY

Introduction

Not only does the way you access the event object differ between Mozilla and IE, but also the properties on the event object.

Source Element

One big difference between IE and the standard event model defined in DOM Level 2 is that events in IE are always dispatched from elements but they should actually be able to be dispatched from any type of node. The problem shows up when you try to get the target when you click on a link with some text in it. IE (using srcElement) returns the link but Mozilla returns the text node (using target) inside the link.

This is fairly simple to fix. We extend the prototype of Event with a getter for srcElement. Inside the getter we find the parent element of the target node of the event.

Event.prototype.__defineGetter__("srcElement", function () {
   var node = this.target;
   while (node.nodeType != 1) node = node.parentNode;
   return node;
}

Notice that the 1 above is the constant for element nodes.

Cancel the event bubble

To cancel the event bubble in the DOM Level 2 event model you call the method stopPropagation on the event object. In IE, however, you cancel the bubble by setting a property called cancelBubble to true.

This one as well, is straight-forward. Add a setter that calls stopPropagation once set. Notice that once the bubbling has been stopped it can not be turned back on.

Event.prototype.__defineSetter__("cancelBubble", function (b) {
   if (b) this.stopPropagation();
});

Preventing default actions

To prevent the default action in IE (like following a link on click) you set the returnValue of the event object to false but in the W3C DOM you call the method preventDefault instead.

Once again we define a setter. This time we call preventDefault if set to false. Notice that once prevented it can not be turned back on.

Event.prototype.__defineSetter__("returnValue", function (b) {
   if (!b) this.preventDefault();
});

From and to element

In mouse over and mouse out events you can get the related element in IE by doing event.toElement and event.fromElement. The way to do this in the W3C DOM is to use event.relatedTarget.

We define the getters for these two properties and check the type of the event. If it is not a mouse over or mouse out event we return null, otherwise we find the parent element of the node and return it.

Event.prototype.__defineGetter__("fromElement", function () {
   var node;
   if (this.type == "mouseover")
      node = this.relatedTarget;
   else if (this.type == "mouseout")
      node = this.target;
   else
      return null;
   var node = this.target;
   while (node.nodeType != 1) node = node.parentNode;
   return node;
});

Event.prototype.__defineGetter__("toElement", function () {
   var node;
   if (this.type == "mouseout")
      node = this.relatedTarget;
   else if (this.type == "mouseover")
      node = this.target;
   else
      return null;
   var node = this.target;
   while (node.nodeType != 1) node = node.parentNode;
   return node;
});

offsetX and offsetY

The properties offsetX and offsetY gives the mouse position relative to the target element and in Mozilla these properties are supported as layerX and layerY for backwards compatibility with AOL/Netscape Navigator 4.x.

To add these we just add two getters that return the layerX and layerY instead.

Event.prototype.__defineGetter__("offsetX", function () {
   return this.layerX;
});

Event.prototype.__defineGetter__("offsetY", function () {
   return this.layerY;
});

Usage

To extend the event object you need to include the ie emu file as well as call the extendEventObject function.

<script type="text/javascript" src="ieemu.js"></script>
<script type="text/javascript">

if (moz) {
   extendEventObject();
}

</script>

Demo

Introduction
The power of JS
Event Listeners
Classic Event Handlers
Event Object
InnerHTML Model
Element Model
Document All Model
Current Style Model
???

Author: Erik Arvidsson