Example of jQuery live()
Last week, I tweeted that I freaking love jQuery's live(). I meant every word too! It's really useful, especially when you're working with ajax. I got some responses on twitter, some people agreed and others weren't really sure where they would use it. So, I'd figure I'd provide an example.
With ajax, it's possible to return HTML to the calling page. Whether you prefer doing it or not, it's possible. Some people prefer to return JSON and build the appropriate HTML, some find it easier to return HTML to the server. Regardless, that HTML that is returned via ajax may or may not contain a link. The link itself may be requested to kick off some javascript function. The problem is, that HTML was loaded in after the fact and isn't necessarily bound to the existing DOM events already on the page.
Well, that's where live() comes in. So, let's start with this plain example:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$('#test').before('<a href="#" class="button">This is a link</a>');
$('.button').click(function(){ alert('foo!'); return false; });
});
</script>
</head>
<body>
<p><a href="#" class="button">Test #1</a></p>
<div id="test"></div>
</body>
</html>
So, we're keeping this example simple. I have a static link on the page and you'll also see that I'm actually creating a link via jQuery and inserting the link before the <div id="test"></div>. Both links work and will alert foo! when you click it. No need for live() here yet. A live example of this can be found here.
I have a file called test.html that contains the following:
<br /><a href="#" class="button">Test #2</a>
So, let's modify our example code a little and pull this in:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$('#test').before('<a href="#" class="button">This is a link</a>');
$('.button').click(function(){ alert('foo!'); return false; });
$('#test').load('test.html');
});
</script>
</head>
<body>
<p><a href="#" class="button">Test #1</a></p>
<div id="test"></div>
</body>
</html>
Live example of the above code. So, we used jQuery's load() to go open test.html and inject the content of test.html straight into <div id="test"></div>. View the page. Click on the links and make sure you get an alert box from javascript saying, foo! Your third link failed didn't it? Why? Because that HTML that was pulled in via ajax wasn't part of the current DOM. You pulled that in after the fact and jQuery is unaware of it.
Let's go read the 1st sentence of live() again: Binds a handler to an event (like click) for all current - and future - matched element. So, by that statement, the HTML pulled from test.html is considered "future" elements. So, now it's time to go tell our time traveling element that it has a click event that it has to adhere to.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$('#test').before('<a href="#" class="button">This is a link</a>');
$('#test').load('test.html');
$('.button').live('click', function(){ alert('foo!'); return false;} ); // this line can be anywhere
});
</script>
</head>
<body>
<p><a href="#" class="button">Test #1</a></p>
<div id="test"></div>
</body>
</html>
Live example of the above code. Notice that we have changed our $('.button').click({ function here }); to $('.button').live('click',{ function here });. So now we have put an click event handler on our existing elements and our time traveling elements. Clicking on all links should now return foo! So, essentially, live() is a nice way of making sure that all current and future elements have event handlers on them. This can be used for any elements, not just links.
Hope this helps someone.
Eric Hynds wrote on 09/22/09 11:16 AM
I use the "livequery" plugin quite a bit as well because it allows you to bind callbacks to new matching elements... live() only works with events at the moment.Charlie Griefer wrote on 09/22/09 11:24 AM
@Ben (and anyone else)... for another example (and some shameless self-promotion) check out a tutorial I wrote at http://tutorial44.learncf.com/. The demo page (http://tutorial44.learncf.com/demo/44) shows that the links that are generated by clicking on the "Show Teams" button will trigger a jQuery getJSON()... and thus need to make use of the live() method.Todd Rafferty wrote on 09/22/09 11:35 AM
@Eric: What am I missing? I just proved on this post that Live() handles current and future elements. For what it's worth, the live() in jQuery 1.2 was rewritten in jQuery 1.3 and as far as I know, live() in jQuery 1.3 is a slimmed down version of "Livequery" plug-in. There are some special cases where you may need to use the heavier "Livequery" to do some jobs, but this isn't one of them.Eric Hynds wrote on 09/22/09 11:50 AM
@Todd for the purposes of your example you are dead on. I use livequery a lot, and thought your readers might find it useful to know that it can delegate to elements as well, and not just specific events. If you're ever going to introduce code (via ajax or whatever) that uses another jQuery plugin, and it does not have a specific event attached to it, livequery becomes necessary.For example I have an app that uses AJAX to load in pages that use the tablesorter plugin. There is no event associated with the tablesorter plugin, so for the code to work, I write something like $("table).livequery(function(){ $(this).tablesorter(); });
Todd Rafferty wrote on 09/22/09 12:10 PM
@Eric: Thanks for clarifying with an excellent example as to why you'd need livequery.Liz wrote on 11/30/09 1:01 PM
I'm lovin' live now too! Made some form processing code alot cleaner when I went to add elements (with event processing) on the fly - thank you! I kinda dismissed it when I initially read about it; but seeing a concrete (and pithy!) example showed me! Too bad no focus/blur events yet are handled yet, but we'll wait and see... I'm a convert now!
Ben Nadel wrote on 09/22/09 10:52 AM
The Live() method is definitely one that I need to look into more. It seems super cool and was definitely dismissive of it the first time I read about it; but, it's gaining a lot of popularity.Good post!