我要做一些大胆的假设,但是我觉得发生的情况是,因为您在设置幕布元素后立即使用强烈的处理锁定了浏览器,所以浏览器从未有机会绘制幕布。
浏览器不会在每次更新DOM时重新绘制。它可能会等待看看您是否正在执行更多操作,然后绘制所需的内容(各种浏览器对此的方法有所不同)。因此,在这种情况下,它可能只在删除幕布之后刷新显示,或者您通过滚动强制重新绘制。
公平警告:这种强烈的处理方式不太好,因为它不仅锁定了您的页面。由于浏览器通常为所有选项卡实现单个Javascript线程,因此您的处理将锁定所有打开的选项卡(=浏览器)。此外,您还面临执行超时和浏览器简单停止脚本的风险(这可能低至5秒)。
以下是解决方法。
如果您可以将处理过程分成较小的块,则可以使用超时运行它(以允许浏览器有呼吸空间)。像这样的东西应该有效:
function processLoop( actionFunc, numTimes, doneFunc ) {
var i = 0;
var f = function () {
if (i < numTimes) {
actionFunc( i++ );
setTimeout( f, 10 )
}
else if (doneFunc) {
doneFunc();
}
};
f();
}
processLoop(function (i){
console.log('number: ', i);
},
10,
function (){
console.log('done!');
});
这实质上是一个 while 循环,但每次迭代都在定时间隔内完成,这样浏览器就有一点时间在其中呼吸。这会减慢处理速度,后续的任何工作都需要进入回调函数,因为循环独立于可能跟随 processLoop 调用的内容。
另一种变化是设置帷幕,使用 setTimeout 调用处理函数,以便让浏览器有时间绘制帷幕,然后在完成后删除它。
var curtain = document.body.appendChild( document.createElement('div') );
curtain.id = "curtain";
curtain.onkeypress = curtain.onclick = function(){ return false; }
setTimeout(function(){
try {
myHeavyProcessingFunction();
}
finally {
curtain.parentNode.removeChild( curtain );
}
}, 40);
如果您正在使用JavaScript库,您可能希望考虑使用现成的解决方案来创建窗帘。大多数库都应该有这样的解决方案,
这里是一个针对jQuery的解决方案,它们可以帮助处理CSS。