3

可能重复:
为什么单击事件处理程序在页面加载后立即触发?

我对 Javascript 函数的理解存在差距,所以我很难理解为什么如果我在没有匿名包装器的情况下定义事件处理程序会自动触发它。

HTML

<a href="#" id="change-html">Change HTML</a>

Javascript #1

var btn = $('#change-html');
btn.click(bindClick(btn)); // bindClick gets executed right away and only once

function bindClick(source){
    console.log('get here');
}

Javascript #2

var btn = $('#change-html');
btn.click(function(){
    bindClick(btn); // bindClick is only executed on the anchor's click event 
});

function bindClick(source){
    console.log('get here');
}
4

2 回答 2

7

其实这里

btn.click(bindClick(btn)); 

您只是将函数的返回值绑定到单击事件,而不是函数本身。
因为在javascript中你可以返回一个函数,这会起作用

var btn = $('#change-html');
btn.click(bindClick(btn));

function bindClick(source){
    return function() {
        console.log('get here');
    }    
}

http://jsfiddle.net/VZ4Gq/

编辑 - 第二个函数是闭包吗?是的,它可能是。让我们看看这个例子

var btn = $('#change-html');
btn.click(bindClick(btn));
// global scope
var inside = "i'm outside a closure";
console.log(inside);
function bindClick(source){
    // local scope 
    var inside = "i'm inside a closure";
    return function() {
        console.log(inside);
    }   
}

http://jsfiddle.net/VZ4Gq/1/

当您尝试此操作时,您首先会记录“我在封闭之外”,然后当您单击按钮时,您会得到“我在封闭内部”。这是因为您实际上创建了一个闭包和 ffunction,当它执行时,它在其原始范围内执行,该范围位于 bindClick()

于 2013-01-25T08:42:56.013 回答
1

问题是 :

btn.click(bindClick(btn));

它将调用 bindClick 方法。尝试用这个来改变那行,看看行为是否与 JavaScript#2 相同:

btn.click({param1: btn }, bindClick);

或者更简单:

btn.click({param1: btn }, $(this));
于 2013-01-25T08:46:26.160 回答