Created: 2008-05-31 21:27
Updated: 2017-05-11 05:50


The Motionbox EventHandler allows you to:

  • Subscribe to elements before they are on the DOM
  • Subscribe to entire classes of elements (eg. subscribe to clicks on all elements with the class ".foo")
  • Subscribe to arbitrary Objects (including DOMElements) which allows you to nicely separate your code
  • Use the same interface to trigger events between Objects and/or DOM elements
  • Limit your actual observers to a minimum (Only 1 per type of event) and still subscribe many elements
  • Maintain a consistent interface among both custom, browser, and on Object events
  • Easily defer your functions (fire using setTimeout by simply adding { defer: true } to your subscriptions)
  • Blur and focus events are supported and bubble in all the supported browsers.


The most notable benefit is: the ability to bind to events before the elements are available in the DOM. This is especially useful for AJAX applications where the DOM is being updated as there is no need to (re)create all your observers.

The EventHandler uses a technique called "event delegation" to handle browser/javascript events. You can read more about event delegation here: The Motionbox implementation is based on the event bubbling ideas brought to YUI by Caridy PatiƱo Mayea:

MBX.EventHandler brings these same conveniences to the prototype.js developer and adds custom event handling as well.

The basic idea is that we listen for key interesting events at the document level (waiting for these events to bubble from their targets). We then fire off these events to any handlers that have been registered with the EventHandler.

The EventHandler also lets you subscribe to arbitrary Objects (and fire arbitrary events on Objects). This makes it really easy to keep your code completely independent of other bits of code. Just subscribe to objects, and have objects fire events on themselves.


MBX.EventHandler listens to Objects, element IDs, classes or single css selectors (p.my_class:first-child).

Right now MBX.EventHandler listens to the following events: "mouseout", "click", "mouseover", "keypress", "change", "blur", "dom:loaded" Any event that bubbles to document is a good candidate for the EventHandler, these are just what we have started with. You can also fire any arbitrary event you want.

IMPORTANT NOTE: "change", "blur" do NOT bubble in IE6,7 and hence are not usable with the EventHandler in those browsers without some additional functions.


function my_listener(evt) {

  <ul id="unordered_list" class="my_ul_class">
    <li id="one" class="my_li_class">First</li>
    <li id="two" class="my_li_class">Second</li>

You can now:

MBX.EventHandler.subscribe("#one", "click", my_listener);  // this will trigger 'my_listener' only by clicking on the li with the id of "one"
// or
MBX.EventHandler.subscribe(".my_li_class", "click", my_listener);  // this will trigger 'my_listener' by clicking either of the LIs below
// or
MBX.EventHandler.subscribe(SomeArbitraryObject, "SomeArbitraryEvent", my_listener);  // this will trigger 'my_listener' by clicking either of the LIs below

All three of the required arguments may be an array:

MBX.EventHandler.subscribe([".my_ul_class", "#one"], ["click", "mouseover"], [my_listener, my_second_listener]);

NOTE: Remember that you can subscribe to these IDs or classes at ANY time after the MBX.EventHandler object is available (well before the dom is ready).

Since we are handling these events outside of the normal browser implementation, you are not confined to browser events:

MBX.EventHandler.subscribe("#one", "my_custom_event_name", my_listener);
// which you could then fire with:
MBX.EventHandler.fireCustom($("one"), "my_custom_event_name");
// or
MBX.EventHandler.fireCustom(SomeArbitraryObject, "SomeArbitraryEvent", { somePayload: 'hi' });

fireCustom also allows the optional extension of custom events with any data of your choosing:

MBX.EventHandler.fireCustom($("one"), "my_custom_event_name", {'customAttribute': "this is cool"});

The line above would add "customAttribute" to the event being passed to the subscribed listeners. In this case, the event being passed to "my_listener" would look like this: evt = {'target': $("one"), 'type': "my_custom_event_name", 'customAttribute': "this is cool"}

NOTE: The target that is being sent to fireCustom and that is being added to the event is an actual DOM element (not an ID or class).

You can also assign functions to be fired at DOM laod (using prototypes "dom:loaded" event) by using



In rare cases, you may want to remove a behavior from a class or id. When subscribing to an event, MBX.EventHandler will return an object to you that you can later use to unsubscribe:

var myEventObj = MBX.EventHandler.subscribe(".my_li_class", "click", my_listener);  // this will trigger 'my_listener' by clicking either of the LIs below
MBX.EventHandler.unsubscribe(myEventObj); // 'my_listener' will no longer be triggered by click events


MBX.EventHandler has the following three public functions:

subscribe(specifiers, eventTypes, functionsToCall, opts) specifiers = an Object or String (or optional array of Strings or Objects) specifying Object, class, id, or css selector to subscribe to eventTypes = a string (or optional array of strings) specifying the name of the events to subscribe to functionsToCall = a function (or optional array of functions) to call upon receiving the event. These functions should accept an Event as their first argument. opts = Object (optional) you can specify {defer: true} to allow these functions to be called with a setTimeout

returns: eventHandlerObject

unsubscribe(handlerObj) handlerObj = the object returned by the subscribe function

fireCustom(target, eventName, opts) target = DOM element or Object eventName = the name of the event to fire (eg, "click" or "my_custom_event") opts = optional object with which to extend the event that is fired

onDomReady(funcs) funcs = Function or Array of functions to be fired at DOM load

Cookies help us deliver our services. By using our services, you agree to our use of cookies Learn more