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.