Forget addEvent, use Yahoo!'s Event Utility
After spending a few hours getting comfortable with Yahoo!'s new Event utility that was recently released along with many other sweet tools via YUIBlog, I became convinced that it is the dopest, sweetest, most tight, most sexiest event utility on the planet. With a little crunching and some gZipping I was able to get this puppy down to meezily weezily 2k.
Furthermore, when I say forget addEvent,
I mean any and every version of addEvent you can think of. This goes for Scott Andrew's original addEvent function, every entry from the addEvent recoding contest, even Prototype's Event observer and its many properties and extensions. I even had a stab at it myself and was pretty impressed with the outcome.
With all that said, not only is the Yahoo! event utility fresh and so clean
by cleaning up some of the mess that other addEvent functions leave behind, it does indeed do quite a few other clever things you wouldn't expect but will knock your socks off. To get started in experiencing this sweet dope tight sexy Event utility, simply plug in the following files into your JavaScript document as follows:
Inserting the YUI Event util
<script type='text/javascript' src='/path/to/YAHOO.js'></script>
<script type='text/javascript' src='/path/to/event.js'></script>
In my particular case after crunching and gZipping it, the filename changed to event.php and I inserted the following lines of code at the very top:
gZipping it up
<?php
ob_start ('ob_gzhandler');
header('Content-type: text/javascript; charset: UTF-8');
header('Cache-Control: must-revalidate');
$offset = 60 * 60 * 24 * 30;
$ExpStr = "Expires: " .
gmdate('D, d M Y H:i:s',
time() + $offset) . ' GMT';
header($ExpStr);
?>
/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
/* The rest of the code goes here...*/
Awesome, now that that's out of the way, lemme tell you just a few of it's slick features...
It's Dope because...
It's got Handler Attachment Deferral. According to the event utility API document:If you attempt to attach a handler to an element before the page is fully loaded, the Event component will attempt to locate the element. If the element is not available, Event periodically checks for the element until the window.onload event is triggered.Oh my F'Gosh! Is that not dope? In a way, it cleans up your mess just incase you goofed.
It's Sweet because...
It's got Automatic Scope Correction. By default in Internet Explorer (using the attachEvent method) when you look at thethis object within your callback function, it looks at the window object whereas according to DOM2 methods it should be the element from which triggered the event. The YUI Event.addListener method corrects this behavior and appropriately changes the scope for you. Albeit some of the entries from the recoding contest fixed this as well, this is indeed another reason why this thing is also so sweet. Also note that Prototype.js does not do this by default but Ryan Campbell has shared with us a workaround to maintain it. Eitherway, no workarounds here, it just straight up works out of the box.
An example of this behavior would be like the following piece:
this correction
YAHOO.util.Event.addListener('myObj','click',callback);
function callback() {
alert(this.id);
// 'this' is a reference to myObj
}
It's Tight because...
It's got Automatic Event Object Browser Abstraction. What this means is that we no longer need to look atwindow.event when sniffing for the event type. This is automatically passed in as the first parameter into the callback function. For example:
Example of event abstraction
function callback(e) {
// that's right. 'e' is what you think it is
// Even for Internet Explorer!
}
Not only is that tight, but they've got built in features that allow you to do all those useful things you normally do with 'e' anyway. For instance, if you want to pull a preventDefault to stop the default action from firing, you can simply do the following (including others):
Preventing default actions
YAHOO.util.Event.addListener(myObj,'click',callback);
function callback(e) {
// not so fast there cowboy
YAHOO.util.Event.preventDefault(e);
// Oh, you don't want bubbly wubbly? Fine.
YAHOO.util.Event.stopPropagation(e);
}
Oh, tired of doing the same two lines of code everytime you want to stop events like that. Well why not just use the handy-dandy stopEvent method.
stopEvent to the rescue
function callback(e) {
// Pa-Zow Sucka!
YAHOO.util.Event.stopEvent(e);
}
Oh yea, you know you like it. But we haven't even scratched the surface yet. Behold its sexy features...
It's Sexy because...
You can send an arbitrary Object to the Event Handler.Say What?
Yea, try this on for size. You can pass in an object as a fourth parameter to the addListener method which becomes available to you as the second parameter in the callback function. For example:Arbitrary Object passing
YAHOO.util.Event.addListener('myelementid', 'click', callback, myOtherObj);
function callback(e,el) {
// el is a reference to myOtherObj
el.className = 'hoopla';
}
Tell me that's not sexy. Go ahead. Try me. Oh, I get it, you want more. Well then, if that doesn't tickle your soft spot, there's yet another optional parameter you can pass into the addListener method which is a boolean (when set to true) that will adjust the scope of this to be set to the custom (arbitrary) object that you passed in. For example:
arbitrary object is accessed through "this"
YAHOO.util.Event.addListener('myelementid', 'click', callback, myOtherObj,true);
function callback() {
// myOtherObj is 'this'
this.className = 'hoopla';
}
Not convinced yet? Let's get naughty
Believe you-me. What I'm about to show is going to make you cry (even my wife is jealous). It's time to have fun with arrays. With the Yahoo! Event utility you can do things that no other addEvent wannabe has even come close to, and that's being able to assign events to multiple objects at the same time with just one line of code. Check this out:Assigning events to an array of objects
var cloner = {
init : function() {
YAHOO.util.Event.addListener(['box1','box2','box3','box4'],'click',this.swap);
},
swap : function() {
$('someDiv').innerHTML = $(this).innerHTML;
}
}
Yea, you saw what just happened. I passed in ['box1','box2','box3','box4'] as the element reference to run the swap method upon the 'click' event. This means that when I click on any of those four boxes, I will get my callback function. Not only does it have to be a string reference of the id's, but it can be mixed strings and objects. For example:
Example of strings and objects mixed
var cloner = {
init : function() {
var obj1 = document.getElementById('box7');
// or if you prefer the $dollar function
var obj2 = $('box39');
// then pass them into the array
YAHOO.util.Event.addListener(['box1',obj1,'box3','box4',obj2],'click',this.swap);
},
swap : function() {
$('someDiv').innerHTML = $(this).innerHTML;
}
}
Alright, so I know what you're thinking. Does that mean I can use Dustin's getElementsByClass function and pass in the array which will, in return, assign listeners to the object collection?Indeed my dear beloved friends. Indeed. Let's pretend we have a bunch of
<div> elements around the page with the class name of 'box' and we want to attach the same function to all of them. Check this out:
assigning events via getElementsByClass
var boxes = getElementsByClass('box',document,'div');
YAHOO.util.Event.addListener(boxes,'click',this.toggle.changer);
Uh huh, it really is that easy. Didn't think it could get better? Oh boy, lest we forget, we can do this with our arbitrary objects as well. See below:
Multiple Arbitrary Objects getting love
var others = ['green','blue'];
YAHOO.util.Event.addListener('red','click',this.toggle.changer,others);
In this case of toggling the display of an element, we can indeed click on one element to toggle many 'other' elements at the same time. Or click on many elements to toggle one element. Or for that matter, we can click on many elements to toggle many other elements...
many to many fiesta
var repubs = ['orange','red'];
var democs = ['blue','green'];
YAHOO.util.Event.addListener(democs,'click',this.messWith,repubs);
I'm in love, anything else I should know about this?
Sure, there's quite a few other useful snippets built into this badboy such as Event.getPageX and Event.getPageY that will return mouse coordinates in a cross-browser friendly way as well as Event.getTime and Event.getCharCode that can prove to be useful as well. I also mentioned a few above already with the stopEvent methods which makes for a helluva convenience.
All in all I have found a new love for event attachment and Yahoo! has exceeded well beyond my expections. As of now this website is currently using my old addEvent but expect that to change in the near future as I will be adopting this utility from here on out.
See this stuff in action
Just for kicks, I put together a little demo of most of these examples into practice for those who want to get a closer look at the code. See Event Listening gone Mad! and feel free to peak at the code and adopt these practices yourself.
recent
- Matador: The Obvious MVC Framework for Node
- Sandboxing JavaScript
- Crouching Ender, hidden command
- Ender.js - The open submodule library
- Qwery - The Tiny Selector Engine
- Klass
- Smallest DOMReady code, ever.
- $script.js - Another JavaScript loader
- About that slowness on Twitter...
- Autocomplete Fuzzy Matching
- JavaScript Cache Provider
- JavaScript Animate
- Asynchronous method queue chaining in JavaScript
- Something changed
- Unofficial Twitter Widget Documentation
i am dustin diaz

