addEventListener, handleEvent and passing objects
Here’s a super awesome trick I had no idea about until someone pointed out you could do this. addEventListener
can take an object as a second argument that will look for a method called handleEvent
and call it! No need for binding “this” so it will pass around the context correctly, the context is the object you’ve just set as the event listener callback.
element.addEventListener("click", obj, false);
Why is this awesome?
We can do things like this:
obj.init();
As you can see our object has an init()
method which binds all the events and just passes in “this” as the callback, handleEvent
then delegates off to whatever method it needs based on the event being triggered, rad.
But wait there’s more
Another awesome thing we can do is change the buttons behaviour without having to remove and re-attach the event handler. The second button in the demo changes what the first button does by redefining the handleEvent method.
<span style='color:#e66170; font-weight:bold; '>if</span> <span style='color:#d2cd86; '>(</span>t<span style='color:#d2cd86; '>.</span>id <span style='color:#d2cd86; '>===</span> <span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>btn</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
<span style='color:#9999a9; '>// Check the button being clicked and do new stuff</span>
<span style='color:#b060b0; '>}</span> <span style='color:#e66170; font-weight:bold; '>else</span> <span style='color:#e66170; font-weight:bold; '>if</span><span style='color:#d2cd86; '>(</span>t<span style='color:#d2cd86; '>.</span>id <span style='color:#d2cd86; '>===</span> <span style='color:#02d045; '>"</span><span style='color:#00c4c4; '>btn3</span><span style='color:#02d045; '>"</span><span style='color:#d2cd86; '>)</span> <span style='color:#b060b0; '>{</span>
<span style='color:#e66170; font-weight:bold; '>this</span><span style='color:#d2cd86; '>.</span>revertHandleEvent<span style='color:#d2cd86; '>(</span><span style='color:#d2cd86; '>)</span><span style='color:#b060b0; '>;</span>
<span style='color:#b060b0; '>}</span>
<span style='color:#b060b0; '>}</span>
}
Makes for some pretty powerful stuff. The third button re-instates the first buttons behaviour back to its original form.
This works in nearly all browsers that support addEventListener, Blackberry 6 browser being one that doesn’t. Blackberry OS7 has fixed this bug.
Polyfill it
IE9 was the first to support addEventListener + handleEvent in the IE family, so for the older ones we can polyfill in support for <IE8 and other non-supporting browsers (BBOS6).
For oldIE it checks if the callback is an object and if it contains handleEvent
. Using call we can change the “this” context to the object passed.
For BBOS6 we wrap a try catch around addEventListener and if the attaching throws, check the callback is an object and has the handleEvent method otherwise don’t swallow the error.
We handle all this by wrapping up the event attaching into a nice method which handles the process for us.
Resources
I’m certainly not the first to document this, see ajaxian article with some great examples.
Even HTML5 boilerplate mobile uses this technique for their fast touch event handling.
[link href=”https://cssn.in/ja/036″]