我有一个页面可以在Javascript中进行一些强烈而持久的计算。我想有一个加载动画来告诉用户正在取得进展。我现在有一个GIF动画,但是当Javascript运行时,整个浏览器窗口会冻结(并且gif不会播放)。然后当它完成时,它会解冻。计算必须是客户端,因此无法在服务器上完成。
有没有办法阻止Javascript冻结页面并在进行计算时停止播放动画?
答案 0 :(得分:12)
您还可以使用HTML5 webworkers
(Wikipedia)在后台运行长时间运行的脚本。这就像javascript的多线程一样。
它可以在除IE之外的最新浏览器中使用。
使用网络工作者发现游戏check it out
答案 1 :(得分:5)
您可以将工作分成小块并使用setTimeout
开始下一次迭代,一旦完成第一次,浏览器就有机会更新用户界面。 (这是因为浏览器使用一个单独的线程,所以如果忙于执行js则不能执行其他操作)
答案 2 :(得分:3)
Javascript处理是单线程的,因此在您的代码运行时,不会运行其他动画代码。
您需要将处理设置为批量运行。我不知道你在处理什么,但是如果你正在做一些可以轻松划分的东西,那么你可以处理前N个项目,然后使用setTimeout来安排下一个块在几毫秒内运行。这样,您就可以让浏览器有时间做其他需要完成的事情。
答案 3 :(得分:1)
如果浏览器死机,那就意味着你正在做一些认真的工作。
解决此问题的唯一方法是每秒脚本执行添加100毫秒的睡眠时间。请查看javascript setInterval()
来电。
答案 4 :(得分:1)
CSS3动画通常会继续运行,即使JavaScript阻止(使用Chrome 40.0进行测试)。
因此,您可以使用SpinKit或spin.js等库来直观显示计算正在进行中。
但请注意CSS3动画的可用性:
caniuse.com
Dispelling the Android CSS animation myths
答案 5 :(得分:1)
你可能不再需要它了,但是万一其他人在谷歌上搜索它,这是另一个简单的解决方案:
*请注意,只有当这个巨大的脚本执行是由长迭代循环引起时才会起作用
- 让你的循环像这样:
function AsyncLoop(i, lastLoop, parameters) {
setTimeout(function () {
if (i < lastLoop) {
//whatever you wanna do here
window.console.log('iteration ' + i + ': ' + parameters[i].whatevs);
i++;
AsyncLoop(i, lastLoop, parameters);
}
}, 0);
}
- 然后称之为:
AsyncLoop(0, incredblyLongObjectArray.length, incredblyLongObjectArray);
这是一个不使用参数的小提琴(所以它更容易理解)并且有一个函数来检测所需的脚本是否已经完成执行:
答案 6 :(得分:0)
我用一个有效的例子(简单的进度指示器)here回答了这个问题。
它使用&#34; yield&#34;当你只想让其他进程成为时间片时,使用起来非常简单(并修改现有的JS循环),并且设置比web worker(我也使用过)更简单,特别是如果你已经有了一个循环与全局变量交互。