动画图像在长时间的 Javascript 方法调用期间不移动

发布于 2024-10-07 14:38:04 字数 338 浏览 0 评论 0原文

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

示例代码:

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

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

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

During a method that runs for 10 seconds to add some elements to the html, the animated gif don't move at all, giving the feel that the web page is stuck. Any way around this.

Example code:

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

One way around this is to breakup the long running method in multiple steps and animating this way, but then you have to write your code this way for each long running method.

Wondering if there is any otherway to do this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

芸娘子的小脾气 2024-10-14 14:38:04

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

});​

实例 * 带有旋转图形的示例

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

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

The only way to ensure that the animation actually occurs is for longRunningMethod to yield to the browser periodically. It's not uncommon for the UI rendering thread to block on the JavaScript thread, so changes you make to the DOM aren't shown until the next time the JavaScript thread yields. You can yield by calling setTimeout with a timeout of 0 (which will be longer than 0ms — obviously — on most browser implementations; many clamp that value to at least 4ms and possibly as much as 10ms).

Example: Here's a script that adds 500 divs, but gives the browser no opportunity to show the work in progress or (usually) animate anything:

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

As you can see, it never yields, and so when you click the button, the page freezes for a moment, and then all 500 divs and the messages appear.

Contrast with this other end of the spectrum, which yields between every 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

Since that yields, you can see the work in progress.

You might notice that the second script takes longer, possibly much longer, in real time to achieve the same result. This is because the yields take time, as does the browser updating the display. In practice, you'll want to find a balance between the first example and the second — something that yields often enough to show progress, but not so often that the process takes an unnecessarily long time to complete.

楠木可依 2024-10-14 14:38:04

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

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

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

If your long running method is doing an synchronous ajax call. Use the asynchronous option on the open method.

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

This will allow your spinning graphics to spin.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文