3

Read some other things on here re: this similar problem but am not sure how to apply this to my dilemma.

I have a jquery function that replaces some HTML in a list.. For example, before the function runs:

<ul id="mylist">
<li id="item1">blah blah blah</li>
<li id="item2">blah blah blah</li>
<li id="item3">blah blah blah</li>
</ul>

Then I have another which runs on click of the LI e.g:

$("#mylist li").click(function () {
alert($(this).attr("id"));
});

Works fine until I dynamically modify the #mylist html, where the alert is blank.

How can I replace the #mylist html and still be able to select the li's found within?

Sampson
  • 251,934
  • 70
  • 517
  • 549
Jeff
  • 33
  • 1
  • 3

2 Answers2

6

To maintain this functionality on all future dynamically-added list items, you should use event delegation with $.on():

$("#mylist").on("click", "li", function(){
  alert( this.id );
});

Read more about $.on(), online at http://api.jquery.com/on/.

Sampson
  • 251,934
  • 70
  • 517
  • 549
  • Wooooow... I am quite new to jQuery, but with this one answer you just solved me 2 problems. Kudos for you, Sir!!! – Andrius Naruševičius May 20 '12 at 01:57
  • 1
    @AndriusNaruševičius This answer was very old - I have just updated it to the correct (modern) way of solving this problem. Don't use `$.live`. – Sampson May 20 '12 at 01:58
  • And you respond fast o.O Okay, will do as you said. Thanks a lot again! – Andrius Naruševičius May 20 '12 at 01:59
  • @AndriusNaruševičius Happy I could be of service. – Sampson May 20 '12 at 01:59
  • `$("a").on("click", function(){ alert("moo"); });` Would you be able to check what I might be doing wrong? .live() worked perfectly for both dynamic and non-dynamic elements and this one also works for normally added elements. But if I added it via .html(), the elements stopped working. – Andrius Naruševičius May 20 '12 at 02:09
  • 1
    @AndriusNaruševičius You're not using delegation in that example. This binds the click handler to the anchor, but if the anchor doesn't exist yet, we have nothing to bind the handler to. Instead, you need to bind the handler to a parent of the anchor. `$.live` would bind to the `document`: `$(document).on("click", "a", function(){ alert("Moo") });`. – Sampson May 20 '12 at 02:11
  • Amazing, just amazing. I finally decided to learn jQuery properly, struggling with basic examples, but the progress is visible as my script already says "Moo"! Thanks again :)) – Andrius Naruševičius May 20 '12 at 02:13
  • @AndriusNaruševičius StackOverflow will definitely come in handy. Good luck! – Sampson May 20 '12 at 02:15
1

When you replace the contents of #mylist you also remove any event handles that were previously attached to its child li elements.

Instead of the normal click function, try using jQuery's live function:

$("#mylist li").live("click", function() {
    alert($(this).attr("id"));
});

Please note that live events work a bit differently than traditional event, especially when it comes to bubbling and event canceling. If this is a problem, then make sure you reattach click events after you manipulate #mylist.

You might also consider using event delegation. Here's a quick example:

$("#mylist").click(function(e) {
    alert($(e.target).closest("li").attr("id"));
});
Community
  • 1
  • 1
Xavi
  • 19,255
  • 13
  • 68
  • 63