Simulating Events Using YUI

Sometimes when managing pages with unobtrusive JavaScript, especially ones leveraging events that need to bubble, two code paths are required: one for the event handler that properly bubbles, and another for the same action triggered by code. For example, a click event is attached to a div, containing many children, including several input elements. If the client clicks on one of the inputs, then both the input and the divclick events fire. However, if you programmatically focus on the element neither event fires, even though it might be desired.

Some browsers have begun to support event emulation allowing engineers to trigger client events, but most are incomplete and there is no standard x-browser way to simulate events. Fortunately, JavaScript Frameworks have come to the rescue, allowing us to simulate client events. YUI has the YUI Test utility, which allows for the emulation of 7 mouse events and 3 keyboard events: click, dblclick, mousemove, mousedown, mouseup, mouseover, mouseout, keydown, keyup, and keypress. So by using YUI there actually is a standard, x-browser way to emulate events.

Most JavaScript Frameworks have an x-browser event handling system, and many keep lists of all the events that you have attached using their utilities. By iterating on the list of cached event handlers, libraries can properly bubble (or capture) events starting from a DOM node and moving up the node tree. Here is a simple example of a click simulator that I wrote using YUI, illustrating how the Test library can leverage the Event utility to simulate events:

Example 1: Click Handler Function

var simulateClickEvent = function(elem) {
	var node = YAHOO.util.Dom.get(elem);
	while (node && window !== node) {
		var listeners = YAHOO.util.Event.getListeners(node, click);

		if (listeners && listeners.length) {
			listeners.batch(function(o) { ? o.scope : this, {target: node}, o.obj);

		node = node.parentNode;

To use simulateClickEvent, simply pass in the ID or pointer to a DOM element. The method tests if the node exists and that it is not equal to the window before continuing its operation. At the end of the while statement, it moves to the parent node of node, and continues that way up the DOM tree until window is reached or null if the node was not properly attached to the DOM. Inside the loop the getListeners method of the Event utility is called, passing in the current node pointer and the desired event (in this case click). If nothing is found for the event/node combination, then YUI will return null, otherwise an array of events objects. Then to simulate events, the listeners array is iterated on and the function attached to the event object is called. In this example, a simple Event Object is created, with only the target key set.

The YUI Test infrastructure is much more robust than my simple example, allowing engineers to specify many more properties of the event that will be passed into the callbacks. However, most of the time you probably wont need that much power and something more rudimentary is acceptable, especially if you do not want to include another JavaScript file into your library. In those cases, I think my little example, with little modifications for your specific requirements, will probably suffice.