事件发生之前触发的JQuery事件处理程序

时间:2013-12-03 07:41:21

标签: javascript jquery event-handling

我正在尝试使用for循环向一系列div添加事件处理程序。应该发生的是,当我单击#containingThumbs div时,应显示其对应的#content div。起初,我遇到了一个问题,即在for循环中分配事件处理程序意味着无论我点击什么#containingThumbs div,只会出现最后一个#content div。

我通过调用外部函数而不是在事件处理程序本身中定义一个函数来解决这个问题,但现在由于某种原因,每个#containingThumbs div上的所有事件处理程序在加载页面后立即触发。之后,点击divs什么都不做。

这是我的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>

这是相关的JS / JQuery代码:

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

1 个答案:

答案 0 :(得分:2)

这一行:

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

调用 expandDiv并将其返回值传递到on,与foo(bar()) 调用 bar的方式完全相同将结果传递给foo。您传入on的内容应该是函数引用。

纠正该代码的几种方法:

  1. 如果您只想要i,因为您想知道点击了哪个div,则不需要它;在expandTab的调用中,this将引用div的DOM元素。因此,如果您更改expandTab以使用this,则可以在(i)后删除expandTab

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

    同样,您必须更改expandTab以使用this作为div。

  2. 您可以使用闭包传递i

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

    假设expandTab期望将该索引视为其第一个参数,并且未使用该事件对象。

  3. 或者,如果您想稍微更改expandDiv,可以通过让jQuery将额外的参数传递给event data来处理它:

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

    expandDiv会使用event.data作为索引。