I have a jQuery function that displays a hidden content on each element in the loop of elements. This work perfectly, but the problem is that when I append new elements to the loop it stops working. It actually works on some elements and doesn’t work on others (strange behavior).
<script type="text/javascript">
jQuery(document).ready(function($) {
$(".see_all").click(function(){
if ($(this).next().css('display') == 'none'){
$(this).next().show();
}
else
if($(this).next().is(':visible')){
$(this).next().hide();
}
});
})
</script>
Is there a problem with my jQuery code? How can I make it work on both newly appended elements and previously displayed elements.
HTML code
<div class="center_container">
<%for users in @user%>
<div class="see_all">
<span style="color:#808080;cursor:pointer">See All Reviews(<%=@beep_count= (@beep.opposes.count + @beep.neutrals.count + @beep.supports.count)%>)</span>
</div>
<div style="display:none;" class="hidden">
No reviews available
</div>
<%end%>
</div>
This will only work if you’re using jQ 1.7+. If you’re not, take a look at jQuery’s
delegate method, which will achieve the same thing in jQuery < 1.7. There’s no reason not to be using the latest version, though 🙂
This is because at the time when you bind your click handler:
It is bound only to the current elements that match the selector
.see_all.What you can do to get around this is use jQuery’s
on()to delegate:This handler is bound to the
body, and then when it detects a click it will look to see if the element clicked matches the selector.see_all. If it does, it will then execute the function. Because it’s bound to thebody, this will work if new.see_allelementsare inserted into the DOM too.If all
.see_allare contained within onediv, use that to delegate on rather thanbody– used that purely as an example. Delegate to the first thing that encompasses all.see_allelements.As a side note, you should use the new API
.on()and.off()for your event binding, since 1.7 they have become the preferred method. Documentation for .on().