alrightgame
alrightgame

Reputation: 391

The .on() delegated event is not firing

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

Answers (3)

zgood
zgood

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

rninty
rninty

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

john Smith
john Smith

Reputation: 17906

try to do the delegation like this on document

 $(document).on('click','#show .img_list li',function(){
...
});

Upvotes: 0

Related Questions