Friday, October 15, 2010

Event Delegation with Mootools

Ever stuck in a situation where you have hundreds of elements and you want to execute same function for each one of them on some event? One possible solution to that approach is simply going through each and every element and hooking the event. However, that is low in performance and doesn't look that elegant. Consider a simple scenerio, there are a lot of images on your page and you want to apply a simple effect that when the mouse is moved on any image, the opacity of the image should be set to 1 and when the mouse is taken out, the opacity is set to 0.4. Let's say that the image is contained in a div with the id "parentDiv". Consider the following code to achieve in a traditional way;

var increaseOpac = function(image){
     image.set({'opacity': 1});
};

var decreaseOpac = function(image){
     image.set({'opacity': 0.4});
};

$$('#parentDiv > img').each(function(img, index){
   img.addEvent('mouseover', increaseOpac.bind(this, img));
   img.addEvent('mouseout', decreaseOpac.bind(this, img));
} );

The above code will work like a charm, however, it's not a good way to do it. This method makes the browser keep track of a lot of work. And if you want to add/remove elements dynamically, then you'll have to hook event on the newly created element as well. Hence, we should go for Event delegation. With event delegation you simply need to add the event on the parent element and it'll delegate it down to it's children. Now, even if you add new element dynamically, since it'll be under the same parent, the event will be automatically apply on it as well. Let's try to achieve the same thing with event delegation;


var increaseOpac = function(event, image){
     image.set({'opacity': 1});
};

var decreaseOpac = function(event, image){
     image.set({'opacity': 0.4});
};

window.addEvent('domready', function(){
    $('parentDiv').addEvent('mouseover:relay(img)', increaseOpac);
    $('parentDiv').addEvent('mouseout:relay(img)', decreaseOpac);
}); 

Now, with event delegation, when the mouse will be moved on any image inside the parentDiv, the event will be fired, however, it will be relayed to the matching selector, which in our case is "img". Another interesting thing is that we don't need to bind any value, the object of the image on which the mouse is moved is sent to the event handler automatically.

For event delegation in mootools, you'll need to download "mootools more" along with mootools core.

No comments:

Post a Comment