0

我的 javascript 文件中有这些行,它工作正常。

handleInput = function(e) {
    var $this = $(this),
    id = $this.attr("id");
    alert(id);
}

....

something.bind("keyup", handleInput);

然后我决定延迟输入功能并添加以下几行:

handleDelayedInput = function(e) {
    setTimeout(handleInput(e), 50);
}

.....

something.bind("keyup", handleDelayedInput);

但是现在alert(id);说未定义,因为我认为我无法将 this 传递给该函数。

我对吗?我该如何解决?有没有更好的方法来做到这一点?

4

4 回答 4

2

那是因为您不再handleInput像从 jQuery 绑定方法调用它时那样传递任何对象上下文。就我个人而言,我会像这样重写整个事情:

something.on("keyup", function(e) {
    var obj = $(this);
    setTimeout(function(obj) {
        alert(obj.attr("id");
    }, 50);
});

请注意使用 ofon()而不是bind()which 现在是首选用法。

于 2012-09-05T20:10:50.237 回答
1

使用apply功能

var handleDelayedInput = function(e) {
    var that = this;
    setTimeout(function() {
        handleInput.apply(that, [e]);
    }, 50);
}

something.bind("keyup", handleDelayedInput); // Assuming something is a 
                                             // jQuery object

这是一个有效的 jsFiddle

handleInput像这样调用setTimeout(handleInput(e), 50);会丢失上下文,所以在这种情况下this不会是你所期望的handleInput

另外,setTimeout应该传递一个函数,而不是函数的结果(除非结果本身就是一个函数)。

于 2012-09-05T20:07:44.947 回答
1

当 jQuery 调用事件处理程序时,它会设置处理程序函数的上下文。在您的第二段代码中调用 handleInput 时,情况并非如此,因此this设置为 default value window

您可以使用applycall设置上下文:

handleInput.call(this, e);

两者之间的区别在于,它apply接受一个参数数组,而您可以call一个一个地传递参数:func.apply(context, arg1, arg2).

所以你的完整代码是:

handleInput = function(e) {
    var $this = $(this),
    id = $this.attr("id");
    alert(id);
}

handleDelayedInput = function(e) {
    var element = this;
    setTimeout(function(){
        handleInput.call(element, e);
    }, 50);
}

something.bind("keyup", handleDelayedInput);

请注意,由于我们使用的是 setTimout,我们需要找到一种方法将元素传递给超时处理函数。此外,在您的代码中,您使用的返回值handleInput(e)作为处理程序函数 - 而不是handleInput.

不过,我同意 Mike 的观点,如果您自己编写了 handleInput 并且可以修改它,那么使用this而不是仅仅传递参数是没有意义的。如果您仍然想在其他地方使用 handleInput 作为直接处理程序,那么保持它的方式是有意义的。

于 2012-09-05T20:07:55.273 回答
0

你可以这样做:

handleInput = function(e) {
   var $this = $(this),
   id = $this.attr("id");
   setTimeout(function() {alert(id);}, 50);
}
于 2012-09-05T20:10:08.277 回答