如何在同步JavaScript运行时显示CSS加载程序
根据我自己的经验,并且与一致,在运行JavaScript代码时不会对UI进行更改 示例如何在同步JavaScript运行时显示CSS加载程序,javascript,html,css,browser,css-animations,Javascript,Html,Css,Browser,Css Animations,根据我自己的经验,并且与一致,在运行JavaScript代码时不会对UI进行更改 示例 当我点击一个按钮“运行脚本”时,我希望加载的动画出现,然后我希望运行一些JavaScript,当JavaScript运行完毕时,我希望加载的动画消失。我创造了一个(可以预见的)失败的世界。代码中最相关的部分是: $('#run-script-btn').on('click', function() { startLoading(); longLoadingScript(10000);
当我点击一个按钮“运行脚本”时,我希望加载的动画出现,然后我希望运行一些JavaScript,当JavaScript运行完毕时,我希望加载的动画消失。我创造了一个(可以预见的)失败的世界。代码中最相关的部分是:
$('#run-script-btn').on('click', function() {
startLoading();
longLoadingScript(10000);
stopLoading();
});
startLoading()
更改CSS以显示加载程序,但在JS完成运行之前,它实际上不会影响UI,此时调用了stopLoading()
,因此本质上我们从未看到加载图标
我提出的一种解决方法是在longLoadingScript()
和stopLoading()
代码周围放置一个setTimeout()
,以便让浏览器有时间在starting()
调用中实际影响UI。工作代码在中,相关部分如下所示:
$('#run-script-btn').on('click', function() {
startLoading();
setTimeout(function() {
longLoadingScript(10000);
stopLoading();
}, 100);
});
问题这是一个好方法吗?是否有更好的/更成熟的模式来处理这种情况?阅读时,使用a更容易理解:
$('#run-script-btn').on('click', function() {
startLoading();
longLoadingScript(10000)
.then(function () {
stopLoading();
});
});
longLoadingScript(ticks) {
var promise = new Promise(function (resolve, reject) {
ajax({
success: function (value?) { promise.resolve(value); },
fail: function (reason) { promise.reject(reason); }
})
});
return promise;
}
IE(非边缘)将需要一个polyfill()这实际上是在您的情况下发生的 1) 浏览器根据从服务器接收的HTML和CSS创建呈现树。然后将渲染树绘制到窗口中 2) 因此,当您在DOM中进行任何更改时,例如显示更改(block/none)。需要重新评估渲染树的部分(或完整)。这被称为回流焊 3) 浏览器缓存所有回流/重绘更改,并在主代码块执行完成后执行 4) 案例1-无setTimeout:主代码块执行+回流/重新绘制所有更改。(显示:阻塞,然后无)。没有可见的更改 案例2-使用setTimeout:主代码块执行+回流(显示:block)+事件循环将setTimeout回调推送到调用堆栈-回流将再次发生(显示:无) 它还可以与0毫秒的setTimeout一起使用 回答您的问题:我觉得这个不错,使用它没有任何问题
$('#run-script-btn').on('click', function() {
startLoading();
setTimeout(function() {
longLoadingScript(100);
stopLoading();
}, 0);
});
另一种解决方案是使用offsetHeight使元件回流。然而,在我的chrome+osx平台上,它似乎不起作用。在firefox中运行良好
$('#run-script-btn').on('click', function() {
startLoading();
var res = $('.page-loading').outerHeight(); // calculates offsetHeight and redraw the element
longLoadingScript(100);
stopLoading();
});
参考:这不是简短的回答,但我会尽量简短 首先,JavaScript是单线程的,所以运行阻塞CPU代码 像
for…loop
或while…loop
这样的操作将阻止中的所有内容
你的网页
运行下面截取的命令,查看stackoverflow中的所有内容如何冻结9秒,并且您还将看到setInterval
也将停止
setInterval(()=>{
console.log(Math.random())
}, 500)
设置超时(()=>{
blocker(9000)//这会使整个网页停止9秒
}, 2500)
功能阻滞剂(ms){
var now=new Date().getTime();
while(true){
如果(新日期().getTime()>now+ms)
返回;
}
}
我的朋友,你错了,javascript是单线程的,因此运行高CPU消耗操作(如for..loop或同步代码)会阻塞网页中的所有内容,你将无法执行事件单击。