Double Nested" this"

时间:2015-11-27 23:48:23

标签: javascript jquery

我今天遇到一个问题,我不确定如何有效地处理。正如您在下面的代码中看到的那样,有三个按钮,当其中一个按钮被单击时,它们都会移动到指定的位置,然后单击的按钮会改变颜色。

这是我最初希望实现的目标,然而背景色立即变化,而不会让按钮有机会到达目的地#34;我尝试使用setTimeout()来解决这个问题,但嵌套函数无法识别this

$('.groupOfButtons').on('click', function(){
    $('#oneButton').animate({
        left:"425px",
        top:"-=24px"    
    }, 1000)
    $('#anotherButton').animate({
        left:"273px",
        top:"+=5px" 
    }, 1000)
    $('#oneMoreButton').animate({
        left:"137px",
        top:"+=34px"    
    }, 1000)
    setTimeout(function(){
        $(this).css({'background-color': 'green'})}, 1000)    // here!
    })
})

如果有人能给我一个很棒的解决方法!但与此同时,我对双嵌套this感到好奇。如何在一个或多个功能中使用它?有可能吗?

2 个答案:

答案 0 :(得分:6)

setTimeout函数回调中,this引用全局window对象。

您需要在该范围之外捕获this的值:

$('.groupOfButtons').on('click', function(){
    var self = this;

    $('#oneButton').animate({
        left:"425px",
        top:"-=24px"    
    }, 1000)
    $('#anotherButton').animate({
        left:"273px",
        top:"+=5px" 
    }, 1000)
    $('#oneMoreButton').animate({
        left:"137px",
        top:"+=34px"    
    }, 1000)
    setTimeout(function(){
        $(self).css({'background-color': 'green'});
    }, 1000);
});

此外,作为评论中的Félix pointed out,您还可以使用功能上的.bind() method更改this的值:

setTimeout(function(){
    $(this).css({'background-color': 'green'});
}.bind(this), 1000);

答案 1 :(得分:1)

要解决实际问题,请保留对点击了哪个按钮的引用,而this仍然引用该按钮。

同样.... setTimeout()会做一些工作,但时间稍微有点机会。为了保证时间安排,请使用promisesjQuery.when()进行汇总。

$('.groupOfButtons').on('click', function() {
    var clickedButton = $(this); // keep a reference to which button was clicked
    var promise1 = $('#oneButton').animate({
        left:"425px",
        top:"-=24px"    
    }, 1000).promise();
    var promise2 = $('#anotherButton').animate({
        left:"273px",
        top:"+=5px" 
    }, 1000).promise();
    var promise3 = $('#oneMoreButton').animate({
        left:"137px",
        top:"+=34px"    
    }, 1000).promise();
    $.when(promise1, promise2, promise3).then(function() {
        clickedButton.css('backgroundColor', 'green')); // here use the reference made earlier.
    });
});

这将保证当所有按钮到达新位置时发生颜色变化,即使某些计算机故障会延迟其中一个或全部。