1

私は4x4のグリッドを持っていて、異なる色が一度に1つのセルに表示されるように色のシーケンスを表示したいと思います。

ループの使用は機能しません:

   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 に答える