JavaScript - 在使用' setTimeout'时丢失上下文

时间:2018-04-22 20:24:02

标签: javascript settimeout

我正在编写一个脚本,用于在迭代元素时更改背景(每次更改后恢复默认值),但我无法让setTimeout工作

$( document ).ready(function() {
  window.onload = Main.init();
});

var Main = {       
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - -  *       
  init: function() {   
    $('#button').click( this.chBackground );    
  },
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - -  *        
  chBackground: function() {
    $('#r1 > div').each( function() {
      $(this).css('background', 'white');
        setTimeout( this.backPrevious , 800);
        //if( this.id == 'b3') return false;
      })
    },        
  backPrevious: function() {      
    $(this).css('background', 'whitesmoke');
  },
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - -  *
}

所以chBackground函数中的代码会运行,但是它没有恢复到默认值(backPrevious)。我正在阅读关于忽略此关键字的上下文,但无论哪种方式都无法弄明白。

3 个答案:

答案 0 :(得分:2)

另一种解决方案是使用没有自己arrow function的{​​{1}},因此不会切换调用上下文。因此,您不必绑定this

this

编辑版:



setTimeout(() => { this.backPrevious(); }, 800);




问题在于$( document ).ready(function() { window.onload = Main.init(); }); var Main = { init: function() { $('#button').click( this.chBackground.bind(this) ); }, backPrevious: function(elem) { $(elem).css('background', 'whitesmoke'); }, chBackground: function() { const elems = document.querySelectorAll('#r1 > div'); for (let i = 0; i < elems.length; i++) { elems[i].style.background = 'white'; setTimeout(() => this.backPrevious(elems[i]), 800); } } } click函数将自己的init限定为this而不是button。所以你必须使用main保持正确的绑定,然后你必须将每个元素作为参数传递给.bind(this)函数。

答案 1 :(得分:1)

尝试这种方式:

setTimeout( this.backPrevious.bind(this) , 800);

但是你在each函数中也失去了上下文,所以这样做:

chBackground        : function() {
    var self = this;
    $('#r1 > div').each( function() {

        $(this).css('background', 'white');
        setTimeout( self.backPrevious.bind(self) , 800);

        //if( this.id == 'b3') return false;
    })
}

答案 2 :(得分:0)

setTimeout实际上是window.setTimeout。因此,setTimeout内部调用的任何内容的调用上下文都将是window对象。您需要指定this backPrevious的{​​{1}}值,指的是您在chBackground中迭代的集合中的元素。

最容易使用箭头功能来避免this混淆:

chBackground: function() {
  $('#r1 > div').each((_, div) => {
    $(this).css('background', 'white');
    setTimeout(() => this.backPrevious.bind(div), 800);
  })
},