views:

34

answers:

2

I'm working on a Javascript library that does not depend on jQuery, though I have jQuery and QUnit available in my tests. In the library, I attach an event to an element the way jQuery does:

if (document.addEventListener) {
  tab.addEventListener('click', MyModule.show, false);
} else if (document.attachEvent) {
  tab.attachEvent('click', MyModule.show);
}

I tried calling $('#tab').click(); in my QUnit test, but it doesn't cause my event handler to be called.

A: 

(not sure) jQuery uses it's own event system on top of the native event system. $(el).click() is invoked directly on that event system and not on the native system. (/not sure)

document.getElementById('tab').onclick();

Is the native equivalent, but you might want to check first if querying for the element actually finds the element. Are you initializing the QUnit tests when the dom is ready?

Also, for attachEvent (IE) you need to prefix events with 'on'.

tab.attachEvent('onclick', listenerFn);

ps. actually I think that the missing prefix 'on' for the IE equivalent was the problem. Change it and test $().click() again.

BGerrissen
I was running the test in Chrome, so I doubt the IE-specific version was the problem.
James A. Rosen
+2  A: 

jQuery has its own event registration system, which is separate from the DOM's event registration. When we call $(something).click(), all registered jQuery handlers and the registered onclick handler will fire, but nothing else would. For example,

document.body.addEventListener('click', function() { alert('event') }, false);
document.body.onclick = function() { alert('onclick'); };      

$('body').click(); // alerts "onclick"

If you call document.body.onclick(), then only the second event will fire and alert "onclick". To get both events to fire, create an event object and dispatch it for the element in question - body in this case. You can find an example here. Unsurprisingly, IE uses a different mechanism to do the same and you need to call fireEvent.

Here's a non cross-browser example for modern browsers (taken from the MDC article above),

var clickEvent = document.createEvent('MouseEvents');
clickEvent.initMouseEvent('click', true, true, window,
    0, 0, 0, 0, 0, false, false, false, false, 0, null);

document.body.dispatchEvent(clickEvent);
Anurag
That's... heinous, but I'm certainly not one to blame the messenger :)
James A. Rosen