简体   繁体   中英

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));
    }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM