是否可以在进入长时间运行的同步过程之前显示一个元素?

时间:2014-10-09 22:26:24

标签: javascript css dom

这是一个非常简单的用例。显示一个元素(一个加载器),运行一些耗尽线程的繁重计算并在完成后隐藏加载器。在启动长时间运行的进程之前,我无法让加载器实际显示出来。在长时间运行的过程之后,它最终显示和隐藏。将css类添加为异步进程吗?

在这里查看我的jsbin:

http://jsbin.com/voreximapewo/12/edit?html,css,js,output

3 个答案:

答案 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