这是一个非常简单的用例。显示一个元素(一个加载器),运行一些耗尽线程的繁重计算并在完成后隐藏加载器。在启动长时间运行的进程之前,我无法让加载器实际显示出来。在长时间运行的过程之后,它最终显示和隐藏。将css类添加为异步进程吗?
在这里查看我的jsbin:
答案 0 :(得分:0)
让当前帧渲染并在setTimeout(1)
之后启动该过程。
或者您可以查询属性并强制重新绘制,如下所示:element.clientWidth
。
答案 1 :(得分:0)
更多可能的答案是,您可以使用HTML5 Web Workers在新线程上进行计算 这样不仅可以显示加载图标,还可以加载它。
有关网络工作者的更多信息:http://www.html5rocks.com/en/tutorials/workers/basics/
答案 2 :(得分:0)
解释其他一些人指出的内容:这是由于浏览器如何排队需要做的事情(即运行JS,响应UI事件,更新/重新绘制页面的外观等)。当JS函数运行时,它会阻止所有其他事情发生,直到函数返回。
以例如:
function work() {
var arr = [];
for (var i = 0; i < 10000; i++) {
arr.push(i);
arr.join(',');
}
document.getElementsByTagName('div')[0].innerHTML = "done";
}
document.getElementsByTagName('button')[0].onclick = function() {
document.getElementsByTagName('div')[0].innerHTML = "thinking...";
work();
};
(http://jsfiddle.net/7bpzuLmp/)
点击此处的按钮会更改div的innerHTML
,然后拨打work
,这应该需要一两秒钟。虽然div的innerHTML
已经改变,但是在事件处理程序返回之前,浏览器没有机会更新实际页面的外观,这意味着等待work
完成。但到那时,div的innerHTML
再次发生了变化,所以当浏览器确实有机会重新绘制页面时,它只显示“完成”而根本没有显示“思考......”。
但是,我们可以这样做:
document.getElementsByTagName('button')[0].onclick = function() {
document.getElementsByTagName('div')[0].innerHTML = "thinking...";
setTimeout(work, 1);
};
(http://jsfiddle.net/7bpzuLmp/1/)
setTimeout
的工作原理是在给定时间过后,在浏览器队列的后面调用给定函数。放置在队列后面的事实意味着它将在浏览器重新绘制页面后被调用(因为之前的HTML更改语句将在setTimeout
添加work
之前排队重新编辑}到队列),因此浏览器有机会在开始耗费时间work
之前显示'思考...'。
所以,基本上,使用setTimeout
。