【问题标题】:Showing a GIF image while javascript processing is stuckjavascript 处理卡住时显示 GIF 图像
【发布时间】:2014-02-25 01:10:00
【问题描述】:

我正在构建一个应用程序,在该应用程序中我正在执行一些冗长(10-15 秒)的 java 脚本执行。我想在执行此操作时显示 gif 图像。我添加了一个 gif 加载图像,在开始处理我的 javascript 之前,我将包含 gif 图像的 div 的样式设置为 display:block,在 javascript 处理完成后,我将其设置回 display:none。我可以看到 gif 图像出现,但它没有显示动画。它卡住了。这个 gif 是一个加载图标。

我的 javascript 函数看起来像这样

function jsFunc(){
// set the div containg the image to display:block
elmDivGif.style.display="block";

Here comes my operation which will take 10-15 secons to finish

// setting the image style to none
elmDivGif.style.display="none";
}

这种方法有什么问题吗?我感觉gif动画和js都是用同一个线程来运行的,而且一次只对一个线程可用。

请指教。

【问题讨论】:

  • 你能贴出动图吗?我认为问题在于图像。你也可以尝试从ajaxload.info下载一个loader
  • 您确定动画 .gif 在 javascript 未运行时可以正常工作吗?
  • JavaScript 是单线程的,因此它不能同时显示动画和执行昂贵的事情。
  • @pimvdb:我认为 OP 使用了动画 gif。与 JavaScript 无关。如果操作错误,请纠正我。
  • @Jcubed - 是的,当没有并行的 JS 处理时,gif 可以工作。我观察到的另一件事是,通过在 JS 执行中放置警报。每当显示警报等待我的操作时,gif 就会开始动画。我认为这进一步证明了它是同一线程的问题。

标签: javascript


【解决方案1】:

Gif 不会显示动画,因为浏览器渲染过程实际上是在运行 javascript 代码的同一线程中。为了实现您想要做的事情,您必须使用Web Workers,但请记住,并非所有浏览器都支持它。

【讨论】:

【解决方案2】:

如果您想同时运行 javascript 和动画 gif,您的 javascript 代码中必须有中断。这可以通过将其拆分为多个函数并使用setTimeout 调用每个函数并延迟约10 毫秒来实现。

【讨论】:

  • 谢谢 Jcubed,我会检查一下并回复。
【解决方案3】:

我在 javascript 处理过程中成功地显示了我的 gif 动画,使用 setTimeout 将其分解并以足够小的突发进行处理,从而不会阻塞显示,它允许其他点击事件等。你没有提到你的过程正在这样做,所以我假设您至少可以将其中一些分解为亚毫秒组。

setTimeout 调用之间,我的 for 循环的 10,000 次迭代被证明是一个延迟 10 毫秒的最佳点。用户体验的总时间最终会感觉更短,因为他们仍然可以与页面交互,并且他们更有耐心,因为他们可以观察到表示工作正在完成的动画。这似乎比“尽快”完成操作的卡住页面更可取。

您项目的setTimeout 调用之间的迭代次数将取决于每次迭代需要多长时间。尝试多次迭代对您来说效果很好,请记住,如果您尝试最大化迭代次数,速度较慢的计算机可能会有不同的体验。

这是使我的应用程序交互更顺畅的伪代码:

masterArray = populateMasterArray();
processInteractively(0, masterArray, ...);
function processInteractively(i, masterList, ...) {
    if (masterList.length > i) {
        for (var x=0; x < 10000 && masterList.length > (i+x); x++) {
            var tempI = i + x;
            //...process this tempI iteration
        }
        i += x; // Lastly update i with however many iterations were processed

        // Wait 10 milliseconds to continue processing; allowing the 
        // browser time to compose itself and display a gif animation
        setTimeout(function() {
            processInteractively(i, masterList, ...);
        }, 10); 
    else {
        outputResults(...variablesBuiltDuringExecution);
    }
}

我注意到的一件事是,即使如果您的循环计数器“太高”,动画可能看起来“卡住”,但它仍然根据自己的时间线制作动画,并且只要可以恢复动画就会跳转到适当的外观。因此,可能在动画中稍稍(或几乎无法察觉)的停顿在美学上是可以接受的,这可以传达正在完成的工作。

【讨论】:

    猜你喜欢
    • 2011-01-15
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 2017-02-13
    • 2022-01-18
    • 2019-07-10
    • 1970-01-01
    相关资源
    最近更新 更多