views:

50

answers:

2

I am working an authorisation system. I have four unordered lists. Let's name them list1, list2, list3 and list4. two of them about countries and rest two are about cities. list1 contains all countries. list2 contains all available countries for one employee. Users are moving one country from list1 to list2. when user clicks list2 i can handle that event and i am populating city's of this country to list3 with jquery. That city list comes from an aspx web page. I want to handle click event of list4. list4 is containing all available cities for employee. I wrote those lines.

$('#clist2 li').click(function() {
    alert('test');
});

But i did not see the alert. How can i handle click event of list4?

+3  A: 

You can use .delegate() here, like this:

$('#clist2').delegate('li', 'click', function() {
    alert('test');
});

$('#clist2 li') gets all the <li> elements inside #clist2 at that time, instead you can bind a handler to #clist2 directly which listens for the click events from any <li> elements (present or added later, their events bubble the same way) to bubble up.

Nick Craver
+1 IMO, the `.live()` method needs to be expunged from the API.
patrick dw
@patrick dw: Why on earth would you want that? I like this delegate method for this specific SO-question but there's plenty of scenarios when it yields less-than-clear code or could cause maintenance headaches. Live is a useful tool which should be used when appropriate.
thenduks
@thenduks - there are downsides to `.live()`, let's take a simple example: `$("[attr=value]").live("click", function() { });`. What did that just do? It performed a very expensive selector to find all elements with that attribute/value pair...then tossed the result away because we don't care about it at all, we only wanted the selector for the `click` handler on `document` in the first place. Compare to: `$("body").delegate("[attr=value]", "click", function() { });` which *doesn't* perform that selector, it's much less expensive.
Nick Craver
@thenduks - Precisely what Nick said, as well as that `.delegate()` causes a person to think in terms of the container the delegate is placed on, and therefore plan their code for greater efficiency. Because `.delegate()` does what `.live()` does, we wouldn't be losing anything if `.live()` didn't exist (as Nick demonstrated). You're absolutely right when you say *"should be used when appropriate"*. Unfortunately, the *"it just works"* factor causes it to be overused.
patrick dw
I think the downside of 'the expensive selector' is being overstated here... Also, I often have code like `$(some_selector).doSomething().find(selector).doSomething().end().live('click', function(){...});` -- in other words, I do the selector for some other purpose anyway. Still, `delegate` (which is pretty new) is nice and would be better for a lot of situations -- I just think there's still use-cases for `live` and wouldn't like to see it removed entirely.
thenduks
+1  A: 

You could use .live() to have all lis get click events regardless of whether they exist at the time of binding or not (eg, the selector just has to match).

thenduks