繁体   English   中英

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

[英]Is it possible to show an element just before entering a long running sync process?

这是一个非常简单的用例。 显示一个元素(一个加载器),运行一些繁重的计算,这些计算会耗尽线程并在完成后隐藏加载器。 在启动长时间运行的程序之前,我无法使加载程序真正出现。 经过长时间的运行,最终显示和隐藏。 添加CSS类是异步过程吗?

在这里查看我的jsbin:

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

让当前帧渲染并在setTimeout(1)之后开始处理。

或者,您可以查询属性并强制重绘,例如: element.clientWidth

作为一个可能的答案,您还可以使用HTML5 Web Workers在新线程上进行计算。这不仅会使您的加载图标显示,还可以使其保持加载状态。

有关网络工作者的更多信息: http : //www.html5rocks.com/en/tutorials/workers/basics/

为了解释其他人指出的内容:这是由于浏览器如何将其需要做的事情排队(例如,运行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更改语句将在setTimeoutwork添加到队列之前将重新绘制排队),因此浏览器有机会在开始耗时的work之前显示“正在思考...”。

因此,基本上,使用setTimeout

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM