0

時間の経過とともに変化する色を表すrgb値の大きな配列が与えられた場合に、ループで更新したいボックスのグリッド(3x2)があります。配列の1つの要素の例は、次のようになります。

[99.58221354166666、99.20004050925925、100.86330150462963]、[59.431727430555554、58.59181712962963、61.26002314814815]、[59.824817708333335、58.83816550925926、61.85647280092593]、[93.02857349537037、95.04584201388889、92.13913194444444]、[48.46075810185185、50.74021701388889、46.878373842592595]、[84.57517939814815、173.51900462962962、62.35618923611111]

以下のコードは、rgb値とすべてを完全に処理します。配列の各要素は、3x2グリッドの「ボックス」に対応します。残念ながら、私のループにはクロージャの問題があるようで、それを理解することはできません。最後の反復でグリッドの色を更新するだけです。そこで、関数のリストを保存して呼び出すように書き直しましたが、実行速度が速すぎて表示されないのか、実際に失敗しているのかわかりません。スリープを追加すると、スクリプトがハングし、ハングした場所で、[スクリプトの続行]をクリックするまでその瞬間に更新されます。その後、最後の更新が表示されます(したがって、最後の更新で表示されていたものから、スクリプトがハングしているように見える2つが表示されるようになりました)。

c1 = $("#cell1");
c2 = $("#cell2");
c3 = $("#cell3");
c4 = $("#cell4");
c5 = $("#cell5");
c6 = $("#cell6");
var cells = [c1, c2, c3, c4, c5, c6];

$(document).ready(function() {
    $.each(test, function(iGrid, grid) {
        var ary_rgb = [];
        var property = "background";
        var updates = [];
        $.each(grid, function (iBox, box) {
            var r = Math.floor(box[0]).toString();
            var g = Math.floor(box[1]).toString();
            var b = Math.floor(box[2]).toString();
            var rgb = 'rgb(' + r + ',' + g + ',' + b + ')';
            updates[iBox] = function () { return cells[iBox].css(property, rgb); };
        });

        for (var i=0; i<updates.length;i++) {
            updates[i]();
        }
    });
});

私はこれを機能させるために数時間を費やし、閉鎖に関するSOや他のサイトを読んでいましたが、何が間違っているのかわかりません。必要に応じて、残りのhtmlを投稿できます。

4

3 に答える 3

1

私はあなたの例を理解し、それがクロージャとどのように関連しているかを理解するにはあまりにも疲れている/愚かですが、あなたが望むものに必要なものよりもはるかに大きくて複雑であると言えます。jQueryの関数によって作成されたものを除いて、このタスクにクロージャを使用する必要はありません。また、再:

最後の反復でグリッドの色を更新するだけです

タイミング関数を使用しなかったため、複数の更新が表示される理由はありません。

これがあなたが説明したことの非常に簡単なデモです:http://jsbin.com/unuvuq/2/editsetTimeout-の使用に注意してください。またはsetInterval、各更新を異なる時間に表示したい場合に必要なものです。

以下のデモのコード。JS:

$(document).ready(function() {

  var colours = [
      "aquamarine",
      "crimson",
      "goldenrod",
      "forestgreen",
      "dodgerblue",
      "orange"];

  $('[id^="cell"]').each(function() {
      var cell = $(this),
          time = 500 * cell.index();
      setTimeout(function() {
          cell.css('background', colours[cell.index()]);
      }, time);
  });

});  

マークアップ:

<div class="container">
    <div id="cell1"></div>
    <div id="cell2"></div>
    <div id="cell3"></div>
    <div id="cell4"></div>
    <div id="cell5"></div>
    <div id="cell6"></div>
</div>

CSS :(何が起こっているかを確認できるようにするためだけに選択されたすべての任意の値)

.container { width: 200px; }

div[id^="cell"] {
  display: inline-block;
  border: 3px solid #000;
  height: 50px;
  width: 50px;
}
于 2012-10-24T17:34:27.540 に答える
0

javascriptが実行されなくなるまでボックスが変更されないと言っている場合、それは予想される動作です。すべてのJavaScriptが返されるまで、ページは視覚的に更新されません。setTimeoutを使用して、各有効な反復後に制御を返すことができます。javascriptでスリープ(スピンループ)しないでください。時限コールバックを使用してください。

function runUpdate(update) {
    if (update.length > 0) {
        update[0]();
    }

    if(update.length > 1) {
        setTimeout(function () {
            runUpdate(update.slice(1));
        }, 0);
    }
}

forループを。に置き換えますrunUpdates(updates);。setTimeout timeパラメータを使用して、ボックスの色が変わる速度を変更できます。

于 2012-10-24T17:16:42.727 に答える
0

これがあなたの目的だと思いますね http://jsfiddle.net/rBLLc/4/

基本的に、あなたが提案したように、すべての更新は次々と急速に行われ、ブラウザーは変更をレンダリングする機会がありません。

(未定義のため、jsfiddleにjavascriptエラーもありましたupdates)。

setTimeoutリンクに示されているように、を使用して更新の間隔を空ける必要があります。

于 2012-10-24T17:59:57.823 に答える