Cross-Browser Events - Java Script

Up until this point, you have seen many different types of browser and feature detection used in each example.In actual code,you want to try to minimize the number of times you use such detection in the main section of code.To achieve this,most developers come up with a cross-browser approach to events so that all the browser and feature detection is done behind the scenes.This section guides you through the creation of such an approach.

The purpose of the cross-browser code in this section is to equalize,as much as possible,the differences between the IE event model and the DOM event model, allowing one set of code to run across all major browsers almost identically. Of course,some limitations exist,such as IE’s lack of support for bi-directional event flow, but it is still possible to cover 80 to 90% of all cases.

The EventUtil object

Whenever you are planning on creating multiple functions that are used in the same task,it’s always best to create a container object to manage them.Doing so makes it easy to figure out where the function is defined when debugging.

In this case,the EventUtil object is the container for all the event-related functions defined in this section. Because there are no properties and you only need one instance of this object,there’s no need to define a class:

var EventUtil = new Object;

Adding/removing event handlers

As you saw earlier, IE uses the attachEvent() method to assign any number of event handlers to an element, whereas the DOM uses addEventListener(). The first method of the EventUtil object creates a common way to assign event handlers and is called addEventHandler()(so as not to be confused with either browser’s implementation).This method accepts three arguments:the object to assign the event handler to,the name of the event to handle,and the function to assign.Because IE doesn’t support event capturing,this method assigns event handlers during bubbling only.Inside the body of the method is a simple detection algorithm designed to use the correct functionality at the correct time:

The code in this method uses feature detection to determine which way to add an event handler.The first branch of the if statement is for DOM-compliant browsers that support the addEventListener() method.When the browser is DOM-compliant, the event handler is added using addEventListener()with the last parameter equal to false, specifying the bubbling phase.

In the second part of the if statement,another feature detect is done for IE’s attachEvent() method.Note that in order to work properly,you must prepend the string “on” in front of the event type(remember, the attachEvent() method accepts the name of the event handler, not the name of the event,as the first parameter).The else clause is simply used for all browsers that are neither DOM- nor IE-compliant.There aren’t too many browsers that fit these criteria, so chances are this branch won’t be used very much.Of course, you can’t just add event handlers; you must also create a way to remove them.To this end, the EventUtil object gets another method called removeEventHandler().As you may expect,this method accepts the same parameters as addEventHandler() and uses pretty much the same algorithm:

As you can see,this code mirrors the addEventHandler() code almost exactly,complete with corresponding feature detects.The only big difference is in the final else statement,where the event handler is set to null and doesn’t use the fnHandler argument at all.

These methods can be used as shown in the following example:

In this code, the onload event handler assigns an onclick event handler to the <div/> with the ID “div1”. When you click on the <div/>, you get the alert that says “Click!”, and then the event handler is removed. Any time that you click the <div/> after that, there will be no alert.

Formatting the event object

One of the best ways to deal with the discrepancies between event objects in IE and the DOM is to make them behave as similarly as possible.Because more browsers use the DOM event model,it only makes sense to make the IE event model match the DOM event model more closely.

The following table is a comparison of DOM and IE event object properties and methods.Often,the event objects and methods are capable of doing the same thing (such as blocking default behaviors), but they are implemented in different ways.This table shows the IE way of doing some of the DOM behaviors. Although you cannot accurately copy all the properties into IE(such as bubbles or cancelable),it is possible to come up with an equivalent method for most.

Formatting the event objectFormatting the event object

DOM Property/Method IE Property/Method

To start, define a new method for EventUtil called formatEvent(), which accepts one parameter, the
event object:

The first thing to do is check for IE on Windows using the browser detection script from the previous chapter. In this case, you must check for the specific browser because this script is targeted at fixing a problem only in IE on Windows:

To make this easy, just go straight down the table of properties and methods and try to make IE comply with the DOM model. The altKey property is already there, the bubbles property cannot be recreated, the button property is there, the cancelBubble property is there, and the cancelable property cannot recreated — that brings up the charCode property.

As mentioned earlier,in IE the character code is contained in the keyCode property on the keypress event; otherwise it’s the correct value. So, if the type of event is keypress,it’s logical to create a charCode property that is equal to keyCode; otherwise, the charCode property should be set to 0:

Continuing down the table,the clientX, clientY, and ctrlKey properties are all the same in IE as in the DOM. We can’t accurately recreate currentTarget or detail, so leave those off. However, you can put a value for eventPhase.this property is always equal to 2 for the bubbling phase because that is all IE supports:

The keyCode property is the same in both browsers, and the metaKey property cannot be recreated in IE, so that brings up pageX and pageY.Although the IE event object doesn’t have equivalent properties,these properties can be calculated by taking the clientX and clientY values and augmenting them with the scrollLeft and scrollTop values of the document body:

The preventDefault() method is next. Just define a method for the event object that sets its returnValue to false:

Note the use of the this object.In the context of an event object method,this refers to the event object.The relatedTarget property can be either the fromElement or toElement property depending on the event type:

The screenX,screenY, and shiftKey properties are all the same, so no work there. That brings up the stopPropagation() method, which simply involves setting cancelBubble to true:

Up next is the target property, which is exactly equivalent to IE’s srcElement property:

For the time property, you just create a Date object with the current date/time and get the milliseconds:

Because the type property is the same in both IE and the DOM,this is the end of the method. However,this method isn’t intended to be used alone. Instead, it is intended to be used inside of another method that gets a reference to the event object.

Getting the event object

Unfortunately,IE and the DOM use very different methods to get the event object.In IE,the event object is tied to the window object although in the DOM it is independent of any other object and is passed in as an argument.Because of this, it is very difficult to make IE’s event model act like Mozilla’s, or vice versa. Instead of trying to make one like the other,you can create a new method that can be used by both browsers called getEvent().

The getEvent() method accepts no arguments and its sole purpose is to return the event object.The first case it deals with is IE, checking for the existence of window.event and then using formatEvent() before returning the event object:

Next up is the DOM case.Remember,DOM-compliant browsers pass the event object as an argument to the event handler.This is when it pays to remember that a function is actually an object that has properties.In this case,the property of interest is called caller.Every function has a caller property that contains a pointer to the method that is calling it.For instance,if funcA() calls funcB(), funcB.caller is equal to funcA. Assuming that an event handler calls EventUtil.getEvent(),then EventUtil.getEvent.caller points to the event handler itself. Remember in Chapter 2,“ECMAScript Basics,” you learned about the arguments property of a function. Because the caller property is a pointer to a function, you can access the arguments property of the event handler. The event object is always the first argument in an event handler,which means you can access arguments[0] in the event handler to get the event object:

This method can now be used inside of an event handler as shown here:

It’s best to put all the EventUtil code defined in the last few sections into a separate file called eventutil.js to make it easy to include this script in any page.


This code is rewritten from an example in the Mouse Events section:

This example works in all DOM-compliant browsers as well as those that are IE-compliant, making use of the target and relatedTarget attributes of the newly formatted event object.

All rights reserved © 2020 Wisdom IT Services India Pvt. Ltd Protection Status

Java Script Topics