Code to add or remove handlers without conflict with legacy code or other project developers.
Modern Web design calls for separating behavior, display, and content. To facilitate separation of behavior, event handler binding should be done in JavaScript instead of in the HTML. This can lead to issues with legacy sites or sites with more than one developer especially when linking external JavaScript files each binding events.
This How-to creates functions, addEvent and removeEvent, to handle the details of binding handlers to events under a wide variety of conditions.
Situation: You're writing new JavaScript to be used throughout a large site. Its functionality requires event handlers to be added or removed through script without stepping on existing handlers.
Let's define some of the terms as used in this article.
There are three ways to bind functions you've written to events.
Inline and assignment both attach the handlers to an object's event property. The handlers can be accessed by object.eventname.toString(). This is NOT the case with addEventListener or attachEvent. These later methods attach the event handlers to another mechanism, which ignores handers bound by other methods, and they cannot be accessed like the other binding methods.
The last two binding methods are consistent with separating behavior from the other elements of Web design.
Inline binding is really the same as assignment to the object's event, only for inline binding the browser creates a wrapper function. This Demo1 link, for example, has the following inline handler for the click event.
onclick="this.innerHTML = (this.innerHTML == 'link demo1'? 'Demo1 link' : 'link demo1'); return false;"
Click the button below to see how the browser has wrapped the code into an event handler.
Browsers wrap the inline code in a function. Some use function onclick(event), while others use function anonymous().
Only one function can be bound to an event by assignment--you can't assign two values to a variable, right? To bind multiple handlers, the handlers need to be wrapped in a single function that is bound to the event. The browser does this for multiple inline event handlers. If you attempt to assign multiple functions without a wrapper function, only the last one will responded to the event. Handlers attached inline replace those attached by assignment.
This is a problem when adding functionality to a page by including multiple JavaScript files that each bind handlers to the same event. This situation commonly occurs for the window.onload event that runs initiation routines. Only one routine, the last one bound, will run. If there is an inline handler, that is the last one bound. So if a developer adds onload="alert('hi');" to the body tag the other initiation routines won't run and the code will be broken. Generally, however, the added functionality will be broken by the other JavaScript files or old inline event handlers. Then a page by page review has to be done to fix the problem.
The built-in functions allow binding multiple handlers to one event without any extra steps; although, they only allow binding a handler once to any event. And, they don't provide anyway to deal with legacy bindings. That is they leave legacy bindings—both inline and by assignment—alone and execute after the legacy handlers.
The addEvent code shown later is designed to deal with this situation. Instead of reviewing and updating every page in your site, just include this script in the page header and use its functions to bind or release handlers. It adds new handlers with the old. The script has six functions; three of which are user APIs, and three are internal to the process. The functions are: