问题的标题表达了我认为我的具体案例背后的终极问题。
我的情况:在点击处理程序中,我想在繁忙的功能开始之前使图像可见(“加载”动画)。然后我想在功能完成后再次使其不可见。而不是我所期望的,我意识到图像永远不会变得可见。我猜这是由于浏览器等待处理程序结束,然后才能进行任何重绘(我相信这有很好的性能原因)。
代码(也在这个小提琴中:http: //jsfiddle.net/JLmh4/2/)
html:
<img id="kitty" src="http://placekitten.com/50/50" style="display:none">
<div><a href="#" id="enlace">click to see the cat</a> </div>
js:
$(document).ready(function(){
$('#enlace').click(function(){
var kitty = $('#kitty');
kitty.css('display','block');
// see: http://unixpapa.com/js/sleep.html
function sleepStupidly(usec)
{
var endtime= new Date().getTime() + usec;
while (new Date().getTime() < endtime)
;
}
// simulates bussy proccess, calling some function...
sleepStupidly(4000);
// when this triggers the img style do refresh!
// but not before
alert('now you do see it');
kitty.css('display','none');
});
});
我alert
在函数之后添加了调用,sleepStupidly
以显示在休息的那一刻,浏览器会重绘,但之前没有。我天真地希望它在将“显示”设置为“阻止”后立即重绘;
作为记录,我还尝试附加 html 标记或交换 css 类,而不是在此代码中显示和隐藏图像。结果相同。
经过我所有的研究,我认为我需要的是能够强制浏览器重绘并在此之前停止所有其他事情。
可能吗?是否有可能以跨浏览器的方式进行?一些我找不到的插件可能......?
我认为也许像'jquery css callback'之类的东西(如在这个问题中:In JQuery, Is it possible to get callback function after setting new css rule?)可以解决问题......但这不存在。
我还尝试将同一事件的显示、函数调用和隐藏在不同的处理程序中分开……但没有。还添加一个setTimeout
来延迟函数的执行(这里推荐:Force DOM refresh in JavaScript)。
谢谢,我希望它也可以帮助其他人。
哈维尔
编辑(设置我的首选答案后):
只是为了进一步解释为什么我选择了 window.setTimeout 策略。在我的真实用例中,我意识到为了给浏览器足够的时间来重绘页面,我必须给它大约 1000 毫秒(比小提琴示例的 50 毫秒要多得多)。我相信这是由于更深的 DOM 树(事实上,不必要的深)。setTimeout let 方法可以让你做到这一点。