• jQuery Live Events

    Feb 16 2009

    jQuery 1.3 came out on January 14th, jQuery 1.3.1 on the 21st, and with them we now have live events built into jQuery.

    Live events are pretty magical at first glance. They allow you to set events only once, and they work forever in the future, even as you're creating new elements and adding them to the page.

    Normally if you ran:

    $('a.wizard').click(function(){
        // do some wizardry
    });
    

    and then later you added wanted to add some more <a class="wizard">s to the page, you would have to re-attach this event handler over and over.

    Live events allow you to add an event that will work forever. This means you only have to add each type of event once. You would only have to write:

    $('a.wizard').live('click', function(){
        // do some wizardry
    });
    

    And your wizard links will work forever, even after you add 100 new wizard links to the page dynamically.

    This magic trick works by attaching the click event to the document. Whenever you click anywhere on the page, the document click event gets called. jQuery compares the target element to your wizard links and triggers your click event if the click came from inside the link.

    You can also do this yourself using the new closest() function. It allows you to do something like this:

    // listen for clicks on the document
    $(document).click(function(e){
        // look for a possible parent element matching a.wizard
        $(e.target).closest('a.wizard').each(function(){
            // wizard it up
        });
    });
    

    These live events can really help with performance. If you're attaching events to 100s of similar elements, like photos in an album, you can also save a lot of memory and speed things up by using live events, or using the example above and checking for events on a common parent element, either document or any element.

    If you're used to using closures to use data within click handlers, you will find they won't work anymore which is probably a good thing. Instead, you can use data() to store any amount of data with that element and get it out later:

    // maybe this is some JSON data you got using Ajax or something
    var wizards = [
       { name: 'Merlin', skill: 'magic' },
       { name: 'Mr. Wizard', skill: 'science' }
    ];
    
    $.each(wizards, function(i, wizard){
        // create a new link, change the text, add the data and append to the body
        $('<a class="wizard"/>')
            .text(wizard.name)
            .data('wizard', wizard)
            .appendTo(document.body);
    });
    

    then you only need to attach the click handler once:

    $(document).ready(function(){
    
        $('a.wizard').live('click', function(){
            // fetch the data back out
            var wizard = $(this).data('wizard');
    
            // get the stuff you need out of the object
            var name = wizard.name;
            var skill = wizard.skill;
    
            // do your thing
            alert(
                "Hello my name is "
                + name
                + "and I'm better than you at "
                + skill
                + "!!!"
            );
        });
    
    });
    

    And you can actually do these things in reverse, the order doesn't matter because of the magic and universality of live events.

    Pretty cool, eh? This way of developing has always been possible using JavaScript, but after learning about this with jQuery 1.3, it changed the way I look at programming with data and events.

    What do you think? Any questions, corrections or suggestions? Leave a comment.