1

我有一个 4x4 的网格,我想显示颜色序列,以便一次在一个单元格中显示不同的颜色。

使用循环不起作用:

   var table = document.getElementById('myTable');
     for(var i=0; i<sequence.length; i=i+3) {
        setTimeout(function(){ table.rows[sequence[i]].cells[sequence[i+1]].className = sequence[i+2]; }, timeout);
        setTimeout(function(){ table.rows[sequence[i]].cells[sequence[i+1]].className = 'black'; }, timeout+1999);
          timeout = timeout+2000;
     }
  } catch(err) { alert(err); }   
}

按顺序使用语句会:

  setTimeout(function(){ table.rows[sequence[0]].cells[sequence[1]].className = 'black'; }, 2999);
  setTimeout(function(){ table.rows[sequence[3]].cells[sequence[4]].className = sequence[5]; }, 3000);
  setTimeout(function(){ table.rows[sequence[3]].cells[sequence[4]].className = 'black'; }, 4999);

(...)

有谁知道为什么循环不起作用?我尝试清除超时但没有喜悦。

4

2 回答 2

2

这是一个经典的闭包问题:当函数被调用时,i 具有循环结束的值。

我喜欢使用对象来封装变量并避免这些问题。例如 :

var table = document.getElementById('myTable');
function C(i, timeout) {
    this.i=i;
    this.timeout = timeout;
}
C.prototype.doThing = function() {
    setTimeout(function(){ table.rows[sequence[obj.i]].cells[sequence[obj.i+1]].className = sequence[i+2]; }, timeout);
    setTimeout(function(){ table.rows[sequence[obj.i]].cells[sequence[obj.i+1]].className = 'black'; }, timeout+1999);
};

 for(var i=0; i<sequence.length; i=i+3) {
        new C(i, timeout)).doThing();
        timeout = timeout+2000;
     }
  } 
于 2012-06-10T13:45:34.633 回答
2

使用这样的自调用函数来传递不同的值,i否则你将传递相同的值:

var table = document.getElementById('myTable');

 for(var i=0; i<sequence.length; i=i+3) {
   (function(i){
    setTimeout(function(){ table.rows[sequence[i]].cells[sequence[i+1]].className = sequence[i+2]; }, timeout);
    setTimeout(function(){ table.rows[sequence[i]].cells[sequence[i+1]].className = 'black'; }, timeout+1999);
      timeout = timeout+2000;
   })(i)

} catch(err) { alert(err); }  
于 2012-06-10T13:47:38.347 回答