To carry on with Javascript, I’m going to talk about a little circular problem I ran into today while dynamically inserting elements into a page.
Let’s say you have a page with a list and you want to do something when someone clicks on the list items:
<ul id="taskList">
<li>first item</li>
<li>second item</li>
...
</ul>
Typically, with jQuery you would attach handlers to the list items like so:
$(document).ready(function(){
$('#taskList li').bind('click', function(){
doSomething();
});
});
So far so good, but suppose you want to insert a list under the element you click on? You will also need to attach handlers for the items you’ve inserted! Let’s see:
$(document).ready(function(){
$('#taskList li').bind('click', function(){
insertSublistUnder(this);
// now let's attach the new handlers
$(this).find('li').bind('click', function(){
insertSublistUnder(this);
// now let's attach the new handlers...
// hey, wait a minute !!!!
});
});
});
You see the pattern here, it could go on and on !!!
So how do you do this?
Short answer: if your version of jQuery is 1.3+, use live instead of bind to attach the handlers (this ensures that all <li> inserted in the future will have their handlers bound automatically:
$(document).ready(function(){
$('#taskList li').live('click', function(){
insertSublistUnder(this);
});
});
But what do you do if you’re stuck in pre-1.3 land ?
Let’s see, we are attaching handlers which in turn insert some items and… attach some handlers which…
We have a bit of recursion here:
$(document).ready(function(){ <------------------
$('#taskList li').bind('click', function(){ |
insertSublistUnder(this); |
// here call this ------------------------/
// on the newly inserted items
});
});
Let’s pack the recursive snippet into a function, say, ‘ attachHandlersUnder’, which takes a (clicked) list element as a parameter:
function attachHandlersUnder(li){
$(li).find('li').bind('click', function(){
insertSublistUnder(this);
attachHandlersUnder(this); // recursive definition
});
}
$(document).ready(function(){
attachHandlersUnder('#taskList'); //
});
Et voila !
Well, in essence… It is actually a bit more complicated, since calling ‘bind’ repeatedly on an element keeps adding handlers to the ones previously set.
Here’s a file with the final code.
So far one person has argued with us about ‘jQuery’s bind() and live()’. Read what they've said and then add to our woes using the form below.
Love what we’ve said? Think we’re talking nonsense? Don’t worry about being polite, just let us have it. We’re not afraid of telling you that you’re talking crap, so don’t be afraid of telling us the same.
adsfasd