【问题标题】:Animated image not moving during long Javascript method call在长时间的 Javascript 方法调用期间动画图像不移动
【发布时间】:2010-12-14 22:44:56
【问题描述】:

在运行 10 秒为 html 添加一些元素的方法期间,动画 gif 根本不动,给人一种网页卡住的感觉。任何方式都可以解决这个问题。

示例代码:

$('#button).click(function() { showAnimatedGif(); longRunningMethod(); hideAnimatedGif(); });

解决此问题的一种方法是将长时间运行的方法分解为多个步骤并以这种方式制作动画,但是您必须为每个长时间运行的方法编写代码。

想知道是否有其他方法可以做到这一点?

【问题讨论】:

  • Don't do that then。你知道 JavaScript 不是多线程的,对吧?
  • 我知道,但必须有办法实现这一点。
  • showAnimatedGif() 在做什么? longRunningMethod() 在做什么?你能发布更多代码吗?
  • showAnimatedGif 基本上显示了具有动画图像的 div。
  • @mrjohn - 长时间运行的方法是同步 JAX 调用?

标签: javascript jquery jquery-events animated-gif jquery-click-event


【解决方案1】:

确保动画实际发生的唯一方法是让longRunningMethod 定期向浏览器让步。 UI 渲染线程阻塞在 JavaScript 线程上的情况并不少见,因此您对 DOM 所做的更改直到 JavaScript 线程下一次退出时才会显示。您可以通过调用 setTimeout 并以 0 的超时来让步(在大多数浏览器实现中,这显然会超过 0 毫秒;许多将该值限制为至少 4 毫秒,甚至可能高达 10 毫秒)。

示例:这是一个添加 500 个 div 的脚本,但浏览器没有机会显示正在进行的工作或(通常)动画任何内容:

jQuery(function($) {

  $("#btnGo").click(function() {
    var n;

    display("Loading...");

    for (n = 0; n < 500; ++n) {
      $("<div/>").html("Div #" + n).appendTo(document.body);
    }

    display("Done loading");

    function display(msg) {
      $("<p/>").html(msg).appendTo(document.body);
    }
  });

});​

Live example * Example with spinner graphic

如您所见,它永远不会产生,因此当您单击按钮时,页面会冻结片刻,然后出现所有 500 个 div 和消息。

与光谱的另一端形成对比,在 每个 div 之间产生:

jQuery(function($) {

  $("#btnGo").click(function() {
    display("Loading...");

    addDivs(0, 500, function() {
      display("Done loading");
    });

    function addDivs(current, max, callback) {
      if (current < max) {
        $("<div/>").html("Div #" + current).appendTo(document.body);
        setTimeout(function() {
          addDivs(current + 1, max, callback);
        }, 0);
      }
      else {
        callback();
      }
    }

    function display(msg) {
      $("<p/>").html(msg).appendTo(document.body);
    }
  });

});​

Live example * Example with spinner graphic

既然这样,您就可以看到正在进行的工作。

您可能会注意到,第二个脚本需要更长的时间,甚至可能更长的时间才能实时获得相同的结果。这是因为产量需要时间,浏览器更新显示也是如此。在实践中,您会希望在第一个示例和第二个示例之间找到一个平衡点——这样的结果经常足以显示进度,但又不会频繁到需要花费不必要的长时间才能完成的过程。

【讨论】:

  • 对 setTimeout 的确切调用是什么样的?
  • @mrjohn:添加了一个有和没有的例子。
  • 关于找到正确平衡的有趣点。我想知道是否有可能在获得最佳结果之前执行浏览器的容量。有点像图形中的 FPS。
  • 问题是我没有加载文本,而是有一个动画 gif,它不会移动/动画。我尝试使用 setTimeout,但没有帮助。
  • @box9:是的。您可以测量 yield 需要多长时间(函数结束和下一个预定函数开始之间的时间),然后在此基础上或多或少地经常 yield。
【解决方案2】:

如果您长时间运行的方法正在执行同步 ajax 调用。在 open 方法上使用异步选项。

xmlHttp.open('POST', ajaxurl, true);

这将使您的旋转图形旋转。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-14
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多