Updated: 2001-04-12: Fixed bugs in fromElement and toElement
Updated: 2001-03-13: Added support for offsetX and offsetY
Not only does the way you access the event object differ between Mozilla and IE, but also the properties on the event object.
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.
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();
});
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();
});
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;
});
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;
});
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>
Introduction
The power of JS
Event Listeners
Classic Event Handlers
Event Object
InnerHTML Model
Element Model
Document All Model
Current Style Model
???