3

所以我正在尝试做一些动态悬停操作,这需要this在 jquery 中使用。由于某种我无法弄清楚的原因,javascriptsetTimeout函数似乎不支持它。

我知道该setTimeout函数不是 Jquery,但如果放在 Jquery 函数中,它不应该能够响应相关this吗?

这是一些示例代码:

var go = false;
var t;
$('.box').mouseenter(function(){
    t = setTimeout(function(){
        go = true;
        alert($('span',this).text());
    },1000);
});
$('.box').mouseleave(function(){
    clearTimeout(t);
    if(go){
        alert($('span',this).text());
    }
});

当悬停 1 秒时,它会警告一个空白,但在 mouseleave 上它会警告正确的文本,即使两个警报都在具有相同选择器的 Jquery 函数内。

为什么会发生这种情况,我该如何解决?

jsfiddle

4

2 回答 2

11

由于回调setTimeout()与主线程分开执行,回调的执行上下文将不同,因此this回调内部不会指向与外部相同的对象setTimeout,在本例中为hovered .box元素。

一种可能的解决方案是使用$.proxy()方法为回调方法传递自定义执行上下文

 $('.box').mouseenter(function(){
    t = setTimeout($.proxy(function(){
        go = true;
        alert($('span',this).text());
    }, this),1000);
 });

演示:小提琴

另一种解决方案是使用闭包变量

$('.box').mouseenter(function(){
    var self = this;
    t = setTimeout(function(){
        go = true;
        alert($('span', self ).text());
    },1000);
});

演示:小提琴

于 2013-08-13T15:47:11.113 回答
4

您可以将其值保存在某处:

$('.box').mouseenter(function(){
    var elem = this;
    t = setTimeout(function(){
        go = true;
        alert($('span', elem).text());
    },1000);
});

您必须这样做的原因是,每当调用新函数时,'this' 都会获得一个新值。因此,当计时器调用您的内部函数时,“this”与鼠标调用您的外部函数时不同。

从技术上讲,“this”被称为执行上下文。

上面的代码所做的是在调用外部函数时创建的闭包内创建一个变量。我们将“this”存储在该变量“elem”中,稍后在超时发生时使用它。

于 2013-08-13T15:50:04.833 回答