Reputation: 391
I've had a similar issue to this in the past because I wasn't using delegated events. Now I am using a delegated event, but it still doesn't work for the newly changed id. What would be the reason that this delegated event doesn't work for dom changes, and how would I remedy this?
Here is an example of two divs swapping the id 'show'. Whenever a 'show' list item is clicked, it is supposed to fire the using the delegated event .on, but it does not.
<style>.hide {display:none;}</style>
<div id="show">
<span id="number" class="hide">2</span>
<span id="list" class="hide">item1,item3</span>
<ul class="img_list">
<li>Something</li>
<li>Something</li>
<li>Something</li>
</ul>
<div class="box">
<button type="button" class="hide" id="checkanswer">check answer</button>
</div>
</div>
<div class="hide">
<span id="number" class="hide">1</span>
<span id="list" class="hide">item1</span>
<ul class="img_list">
<li>Something</li>
<li>Something</li>
</ul>
<div class="box">
<button type="button" class="hide" id="checkanswer">check answer</button>
</div>
</div>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
var selection_required=$('#show #number').html();
$('#show').on('click', '.img_list li', function(){
if($(this).hasClass("selected")){
$(this).removeClass("selected");
}
else{
$(this).addClass("selected");}
if ($('.selected').length==selection_required){
$("#show #checkanswer").fadeIn( "slow", function() {});
}
else{
$("#show #checkanswer").fadeOut( "slow", function() {});
}
});
$('#checkanswer').click(function(){
parent=$(this).parent().parent();
next=$(this).parent().parent().next();
parent.removeAttr("id");
parent.addClass("hide");
next.attr("id","show");
next.removeClass("hide");
selection_required=next.find('#number').html();
item_array=next.find("#list").html();
next.show();
});
</script>
Upvotes: 3
Views: 105
Reputation: 12581
As mentioned by other commenters you need this for your .on
event:
$(document).on('click', '#show .img_list li', function () {...
But you also need to reset your .selected
class in that .on
event like so:
$(document).on('click', '#show .img_list li', function () {
if ($(this).hasClass("selected")) {
$(this).removeClass("selected");
}
else {
$(this).addClass("selected");
}
if ($('.selected').length == selection_required) {
$("#show #checkanswer").fadeIn("slow", function () { });
$('.selected').removeClass('selected');
}
else {
$("#show #checkanswer").fadeOut("slow", function () { });
}
});
The $('.selected').removeClass('selected');
is needed.
Upvotes: 1
Reputation: 1082
Delegation works by binding an event listener to one element that receives events that bubble up from its children. The reason it’s used when elements change dynamically is because the event is still attached to an element; if you make the delegate an element that changes, it defeats the purpose. Instead, you can go one level up, wherever that is – or even just to document
.
$(document).on('click', '#show .img_list li', function(){
if($(this).hasClass("selected")){
$(this).removeClass("selected");
}
else{
$(this).addClass("selected");}
if ($('.selected').length==selection_required){
$("#show #checkanswer").fadeIn( "slow", function() {});
}
else{
$("#show #checkanswer").fadeOut( "slow", function() {});
}
});
Your first if
can be $(this).toggleClass("selected")
, by the way.
Upvotes: 2
Reputation: 17906
try to do the delegation like this on document
$(document).on('click','#show .img_list li',function(){
...
});
Upvotes: 0