5

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

示例代码:

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

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

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

4

2 回答 2

6

确保动画实际发生的唯一方法是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);
    }
  });

});​

实时示例*带有微调器图形的示例

如您所见,它永远不会产生,因此当您单击按钮时,页面会冻结片刻,然后出现所有 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);
    }
  });

});​

实时示例*带有微调器图形的示例

由于这会产生,您可以看到正在进行的工作。

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

于 2010-12-14T22:58:55.920 回答
0

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

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

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

于 2015-10-28T16:13:40.417 回答