我有一个页面,它用 Javascript 进行一些密集且持久的计算。我想要一个加载动画来告诉用户正在进行的进度。我现在有一个动画 gif,但在 Javascript 运行时整个浏览器窗口冻结(并且 gif 不播放)。然后完成后,它就会解冻。计算必须在客户端进行,因此不能在服务器上完成。
有没有办法防止 Javascript 在计算时冻结页面并停止播放动画?
I have a page which does some intense and long lasting calculations in Javascript. I would like to have a loading animation to tell the user progress is being made. I have an animated gif now, but the whole browser window freezes (and the gif does not play) while the Javascript is running. Then when it's done, it unfreezes. The calculations must be client-side so they cannot be done on a server.
Is there a way to keep Javascript from freezing the page and stopping animations from playing while it's doing calculations?
发布评论
评论(7)
您还可以使用 HTML5
webworkers
(Wikipedia) 在后台运行长时间运行的脚本。这就像 JavaScript 的多线程一样。它可以在除 IE 之外的最新浏览器中运行。
发现一个使用 webworkers 的游戏看看
You can also use HTML5
webworkers
(Wikipedia) to run long running scripts in the background. It is just like multi threading for javascript.It will work in latest browsers except IE.
Found a game using webworkers check it out
您可以将工作分成小块,并使用 setTimeout 开始下一次迭代,一旦第一次迭代完成,浏览器就有机会更新用户界面。 (这是因为浏览器使用单线程,所以如果忙于做js就无法做其他事情)
You could split the work in little small pieces and use a
setTimeout
to to begin the next iteration, once the first has finished, that way the browser has a chance to update the user interface. (this is because the browser uses one single thread, so if it is busy doing js it can't do other things)JavaScript 处理是单线程的,因此当您的代码运行时,不会运行其他动画代码。
您需要将处理设置为批量运行。我不知道你在处理什么,但是如果你正在做一些可以轻松划分的事情,那么你可以处理前 N 个项目,然后使用 setTimeout 安排下一个块在几毫秒内运行。这样,您就可以给浏览器时间来完成其他需要完成的事情。
Javascript processing is single threaded, so while your code is running, no other animation code will run.
You'll need to set up your processing to run in batches. I don't know what you are processing, but if you are doing something that can be divided up easily, then you can process the first N items, then use setTimeout to schedule the next chunk to run in a few milliseconds. That way, you give the browser time to do other stuff that needs to be done.
您可能不再需要它,但为了防止其他人在谷歌上搜索它,这里有另一个简单的解决方案:
*注意,只有当这个巨大的脚本执行是由长迭代循环引起时它才会起作用
- 让您的循环类似于this:
-然后这样调用它:
这是一个不使用参数的小小提琴(因此更容易理解),并带有一个函数来检测所需的脚本是否已完成执行:
https://jsfiddle.net/or1mrmer/
You probably don't need it anymore, but just in case anyone else is googling it, here's another simple solution:
*note that it would only work if this huge script execution is being caused by a long iteration loop
-make your loop something like this:
-then call it like:
Here's a little fiddle without using parameters (so it's easier to understand) and with a function to detect if the desirable script has finished executing:
https://jsfiddle.net/or1mrmer/
如果浏览器冻结,则意味着您正在做一些认真的工作。
解决这个问题的唯一方法是在脚本执行时每秒添加 100 毫秒的睡眠时间。请查看 javascript
setInterval()
调用。If browser freezes, that means you are doing some serious work.
The only way to solve this is to add 100ms of sleep every second of the script execution. Please look at javascript
setInterval()
call.即使 JavaScript 被阻塞,CSS3 动画通常也会继续运行(使用 Chrome 40.0 进行测试)。
因此,您可以使用 SpinKit 或 spin.js 以可视化计算正在进行中。
但是,请注意 CSS3 动画的可用性:
caniuse.com
消除 Android CSS 动画迷思
CSS3 animations typically continue running even if JavaScript is blocking (tested with Chrome 40.0).
So you can use libraries like SpinKit or spin.js to visualize that the calculation is ongoing.
However, note the availability of CSS3 animations:
caniuse.com
Dispelling the Android CSS animation myths
我在此处用一个功能示例(带有简单的进度指示器)回答了这个问题。
它使用“yield”,并且当您只想允许其他进程一个时间片时,使用起来非常简单(并修改现有的 JS 循环),并且它比 Web Worker(我也使用过)更容易设置,特别是如果您已经有一个与全局变量交互的循环。
I answered this with a functioning example (with simple progress indicator) here.
It uses "yield" and is extremely simple to use (and modify existing JS loops) when you simply want to allow other processes a timeslice, and it is simpler to set up than web workers (which I have used as well), especially if you already have a loop interacting with global variables.