0

我有一个盒子网格(3x2),我想在一个循环中更新它,因为它有大量 rgb 值表示随时间变化的颜色。数组的一个元素的示例如下所示:

[[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 网格中的一个“盒子”。不幸的是,我的循环似乎有一个关闭问题,我无法弄清楚。它仅在最后一次迭代时更新网格的颜色。所以我重写了它来存储一个函数列表,然后调用它们,但我不知道它是否只是执行得太快以至于我看不到它,或者它是否真的失败了。如果我添加一个睡眠,脚本将挂起,无论它挂在哪里,它都会更新那一刻,直到我单击继续脚本。之后它会向我显示最后一次更新(所以我已经从看到最后一次更新到看到两个带有明显挂起的脚本)。

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/edit。如果您想在不同时间查看每个更新,请注意使用setTimeout- that or is what you need。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 时间参数来更改框更改颜色的速率。

于 2012-10-24T17:16:42.727 回答
0

我想这就是你想要的,不是吗?http://jsfiddle.net/rBLLc/4/

基本上,就像您建议的那样,您的所有更新都在迅速发生,一个接一个,浏览器永远没有机会呈现更改。

(由于未定义,jsfiddle 中还有一个 javascript 错误updates)。

setTimeout您需要使用链接中所示的方式分隔更新。

于 2012-10-24T17:59:57.823 回答