首页 > 解决方案 > 如何避免“跳跃”的 UI 更新?

问题描述

我想运行模拟并更新进度条,但进度条以“跳跃”的方式更新。例如。它从 21% 上升到 34% 到 76%。我想从 21% 到 22% 再到 23% 等等。

将其视为SSCCE

http://embed.plnkr.co/XIKxpV6oWyWiwklFBSLh/

HTML

<button>Simulate</button>

JS

$(document).ready(function () {
  var $button = $('button');

  var worker = new Worker("worker.js");
  worker.addEventListener("message", function(e) {
    if (e.data) {
      switch (e.data.cmd) {
        case "progress":
          $button.text((e.data.value / 250).toFixed(0) + "%");
          break;
        case "complete":
          $button.text("Simulate");
          break;
      }
    }
  });
  $button.on("click", function() {
    worker.postMessage("start");
  });
});

工人

this.addEventListener("message", function(e) {
  if (e.data === "start") {
    for (var n = 0; n < 250000000; ++n) {
      if (n % 10000 === 1) {
        this.postMessage({cmd: "progress", value: n / 10000});
      }
    }
    this.postMessage({cmd: "complete"});
  }
});

如何让它顺利更新?为什么一开始更新不顺畅?

标签: javascript

解决方案


您可以更改progress以提供填充值。

它不流畅的原因是它不会发布所有值的进度值,只有每个值10000(如果您尝试发布每个值,您的浏览器很可能会冻结)

if (n % 10000 === 1) {
  this.postMessage({cmd: "progress", value: n / 10000});
}

所以你没有得到所有可能的 % 值,你需要填写。

像这样的东西

$(document).ready(function () {
  var $button = $('button');

  var last = 0
  var worker = new Worker("worker.js");
  worker.addEventListener("message", function process(e) {
    if (e.data) {
      switch (e.data.cmd) {
        case "progress":
          var next = (e.data.value / 250)
          var current = last

          // fill values
          // from last % to new %
          for (; current < next; ++current) {
            $button.text(current + "%")
          }

          last = current

          $button.text(next.toFixed(0) + "%");

          break;
        case "complete":
          $button.text("Simulate");
          break;
      }
    }
  });

  $button.on("click", function() {
    worker.postMessage("start");
  });
});

推荐阅读