user3060388
user3060388

Reputation: 1

JQuery event handlers firing before event occurs

I'm trying to add event handlers to a series of divs using a for loop. What should happen is that when I click a #containingThumbs div, its corresponding #content div should be displayed. At first, I ran into the issue where assigning event handlers in a for loop meant that no matter what #containingThumbs div I clicked, only the last #content div would appear.

I fixed that, by calling to an external function instead of defining one in the event handler itself, but now for some reason, all the event handlers on every #containingThumbs div fires as soon as the page is loaded. After that, clicking on the divs does nothing whatsoever.

Here's my HTML:

<div id="containingThumbs">
<div><img src="1.png"></div>
<div><img src="2.png"></div>
<div><img src="3.png"></div>
<div><img src="4.png"></div>
<div><img src="5.png"></div>
<div><img src="6.png"></div>
<div><img src="7.png"></div>
<div><img src="8.png"></div>
<div><img src="9.png"></div>
<div><img src="10.png"></div>
<div><img src="11.png"></div>
<div><img src="3.png"></div>
<div><img src="4.png"></div>
<div><img src="5.png"></div>
<div><img src="6.png"></div>
<div><img src="7.png"></div>
<div><img src="8.png"></div>
</div>

<div id="content">
<div><img src="1.png"></div>
<div><img src="2.png"></div>
<div><img src="3.png"></div>
<div><img src="4.png"></div>
<div><img src="5.png"></div>
<div><img src="6.png"></div>
<div><img src="7.png"></div>
<div><img src="8.png"></div>
<div><img src="9.png"></div>
<div><img src="10.png"></div>
<div><img src="11.png"></div>
<div><img src="3.png"></div>
<div><img src="4.png"></div>
<div><img src="5.png"></div>
<div><img src="6.png"></div>
<div><img src="7.png"></div>
<div><img src="8.png"></div>
</div>

and here's the relevant JS/JQuery code:

function expandDiv(j){
    //first hide all content that is currently displayed, if any
    $("#content div").css("display","none");
    //then display only the right content div
    $("#content div:nth-child("+j+")").css("display","inherit"); 
}

function makeInteractive(){
    for (var i = 0;i<$("#containingThumbs").children().length;i++){
        $("#containingThumbs").on("click","div",expandDiv(i));
    }
}

Upvotes: 0

Views: 118

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074258

This line:

$("#containingThumbs").on("click","div",expandDiv(i));

calls expandDiv and passes its return value into on, exactly the way foo(bar()) calls bar and passes the result into foo. What you pass into on should be a function reference.

Several ways to correct that code:

  1. If you just want i because you want to know which div was clicked, you don't need it; within the call to expandTab, this will refer to the DOM element for the div. So if you change expandTab to use this, you can just remove the (i) after expandTab:

    function makeInteractive(){
        for (var i = 0;i<$("#containingThumbs").children().length;i++){
            $("#containingThumbs").on("click","div",expandTab);
            // No (i) ---------------------------------------^
        }
    }
    

    Again, you'd have to change expandTab to use this for the div.

  2. You can pass i using a closure:

    function makeInteractive(){
        for (var i = 0;i<$("#containingThumbs").children().length;i++){
            $("#containingThumbs").on("click","div",makeHandler(i));
        }
        function makeHandler(index) {
            return expandDiv(index);
        }
    }
    

    That assumes expandTab is expecting to see that index as its first argument, and isn't using the event object.

  3. Or if you want to change expandDiv a bit, you can handle it by having jQuery pass you the extra argument as event data:

    function makeInteractive(){
        for (var i = 0;i<$("#containingThumbs").children().length;i++){
            $("#containingThumbs").on("click", "div", i, expandDiv);
            // Note the `i` --------------------------^           ^--- no ()
        }
    }
    

    expandDiv would use event.data as the index.

Upvotes: 2

Related Questions