jquery – bind, click, and live

11 03 2010

I recently decided to update my JavaScript skills and make a more intense effort to master jquery. There is excellent online documentation available at http://api.jquery.com but I found that while it answers many questions, it also raises others. So, my questions for today concern how to bind a handler to an event property such as click and how to use .live(), a jquery method that is useful if you wish to add an additional element dynamically and have it behave the same as other such elements.

Here is the problem, to wit:

<!DOCTYPE html>
<html>
<head>
<style>
p { color:red; margin:5px; cursor:pointer; }
p.hilite { background:yellow; }
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<div id="container">
<p>First Paragraph</p>
<p>Second Paragraph</p>
<p>Yet one more Paragraph</p>
</div>
<input id="d" type="button" value="hide"> <input id="b" type="button" value="add">
<script src="theproblem.js"></script>
</body>
</html>

This bit of html has three paragraphs and allows you to dynamically add a paragraph vis a vis the javascript contained in theproblem.js, as follows:


$(document).ready(function(){
$("p").click(function () {
$(this).slideUp();
});
$("p").hover(function () {
$(this).addClass("hilite");
}, function () {
$(this).removeClass("hilite");
});
$("#d").click(function() {
$("p").click();
});
$("#b").click(function() {
$('#container').append('<p>New Paragraph</p>');
});
});

Note that in the above script the snippet $("#d").click(function(){ is essentially shorthand for the following:


$("#d").bind('click', function(){

In both cases the element with an id of “d” is having it’s click event property bound to a handler that ought to hide the paragraphs of the document by causing in turn the event handler for each paragraph’s click event property to be invoked. But, the dynamic paragraphs lack any such handler!

If you view the html file with its accompanying javascript in a browser, try adding a dynamic new paragraph. That part should work for you. However, when you click the hide button, you’ll notice that only the static paragraphs get hidden with the dynamic paragraph remaining unaffected.

What can you do? This is where the jquery .live() method comes into play as you can use it to make certain that the properties of the static paragraphs are also shared by any dynamically added paragraphs. There are also some subtle points that need to be observed when you use .live().

I’ve amended the html to make it a little more interesting and am using a different and more useful javascript file, lifestuff.js.


<!DOCTYPE html>
<html>
<head>
<style>
p { color:red; margin:5px; cursor:pointer; }
p.hilite { background:yellow; }
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<div id="container">
<p>First Paragraph</p>
<p>Second Paragraph</p>
<p>Yet one more Paragraph</p>
</div>
<input id="h" type="button" value="hide"> <input id="s" type="button" value="show"> <input id="a" type="button" value="add">
<script src="livestuff.js"></script>
</body>
</html>

The javascript file livestuff.js consists of the following:


var n = 0;
var html = '';
$(document).ready(function(){
$("p").click(function () {
$(this).slideUp();
});
$("p").hover(function () {
$(this).addClass("hilite");
}, function () {
$(this).removeClass("hilite");
});
$("#h").click(function() {
$("p").click();
});
$("#a").click(function() {
n = document.getElementsByTagName('p').length;
n++;
html = '<p>Paragraph #' + n + '</p>';
$('#container').append(html);
});
$("#s").click(function() {
$("p").slideDown();
});
$("p").live('click', function() {
$(this).slideUp();
});
$("p").live('mouseover', function() {
$(this).addClass("hilite");
});
$("p").live('mouseout', function() {
$(this).removeClass("hilite");
});
});

The snippet:

$("p").live('click', function() {
$(this).slideUp();
});

ensures that whenever another paragraph is added, it will experience a click event just the way the static paragraphs do.

Now, I thought that I could handle the ‘hover’ property for the dynamic paragraphs by writing some code like this:

$("p").live('hover',function () {
$(this).addClass("hilite");
}, function () {
$(this).removeClass("hilite");
});

That actually messed things up a bit. Every paragraph, both the static and the dynamic ones turned yellow and stayed that way when I pointed to them. What I had to do was to write the following snippets:

$("p").live('mouseover', function() {
$(this).addClass("hilite");
});
$("p").live('mouseout', function() {
$(this).removeClass("hilite");
});

By addressing each event property separately with .live() I was able to have the dynamic paragraphs behave just the same as the static ones for click, mouseover and mouseout events.

Advertisements

Actions

Information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: