强制DOM重绘与javascript按需 [英] force DOM redraw with javascript on demand

查看:129
本文介绍了强制DOM重绘与javascript按需的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我的案例:
在一个点击处理程序中,我想要在繁忙功能开始之前使图像可见(加载动画)。然后我想在函数完成后再次看到它。
而不是我的预期,我意识到图像永远不可见。我猜这是由于浏览器等待处理程序结束,在它可以进行任何重绘之前(我相信有很好的性能原因)。



代码(也在这个小提琴: http://jsfiddle.net/JLmh4/2/



html:

 < img id =kittysrc =http://placekitten.com/50/50style =display:none> 
< div>< a href =#id =enlace>点击查看cat< / a> < / DIV>

js:

 code> $(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)
;


//模拟bussy proccess,调用一些函数...

sleepStupidly(4000);

//当这触发img样式
//但不是之前
alert('now you do see it');

kitty.css('display','none');
});
});

我已经添加了 alert sleepStupidly 功能表明,在休息的那一刻,浏览器重绘,但不是之前。我无辜地期望在将显示设置为阻止之后立即重绘;



对于记录,我还尝试附加html标签或交换css类,而不是显示和隐藏在此代码中的图像。相同的结果。



在我所有的研究之后,我认为我需要的是强制浏览器重绘的能力,并阻止其他事情直到那时。



可以吗?是否可能以交叉浏览器的方式?有些插件我不能找到可能...?



我以为可能像'jquery css回调'(如这个问题:在JQuery中,是否可以得到设置新的CSS规则后的回调函数?)会做窍门...但是不存在。



我还试图分离显示,函数调用和隐藏在同一事件的不同处理程序...但没有。还要添加一个 setTimeout 来延迟函数的执行(这里建议:强制JavaScript中的JavaScript刷新)。



谢谢,我希望它也可以帮助别人。



javier



编辑(设置我的首选答案后):



只是为了进一步解释为什么我选择了window.setTimeout策略。
在我的实际使用情况下,我意识到为了给浏览器足够的时间来重绘页面,我不得不给它大约1000毫秒(比小提琴示例的50多)。这相信是由于DOM树更深(实际上是不必要的深)。
setTimeout let方法可以让你这样做。

解决方案

使用 window.setTimeout() 有一些短暂的不明显的延迟来运行缓慢的功能:

  $文件).ready(function(){
$('#enlace')。click(function(){
showImage();

window.setTimeout(function() {
sleepStupidly(4000);
alert('now you do see it');
hideImage();
},50);
});
});

现场演示


The title of the question expresses what I think is the ultimate question behind my particular case.

My case: Inside a click handler, I want to make an image visible (a 'loading' animation) right before a busy function starts. Then I want to make it invisible again after the function has completed. Instead of what I expected I realize that the image never becomes visible. I guess that this is due to the browser waiting for the handler to end, before it can do any redrawing (I am sure there are good performance reasons for that).

The code (also in this fiddle: 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');
    });
});

I have added the alert call right after the sleepStupidly function to show that in that moment of rest, the browser does redraw, but not before. I innocently expected it to redraw right after setting the 'display' to 'block';

For the record, I have also tried appending html tags, or swapping css classes, instead of the image showing and hiding in this code. Same result.

After all my research I think that what I would need is the ability to force the browser to redraw and stop every other thing until then.

Is it possible? Is it possible in a crossbrowser way? Some plugin I wasn't able to find maybe...?

I thought that maybe something like 'jquery css callback' (as in this question: In JQuery, Is it possible to get callback function after setting new css rule?) would do the trick ... but that doesn't exist.

I have also tried to separte the showing, function call and hiding in different handlers for the same event ... but nothing. Also adding a setTimeout to delay the execution of the function (as recommended here: Force DOM refresh in JavaScript).

Thanks and I hope it also helps others.

javier

EDIT (after setting my preferred answer):

Just to further explain why I selected the window.setTimeout strategy. In my real use case I have realized that in order to give the browser time enough to redraw the page, I had to give it about 1000 milliseconds (much more than the 50 for the fiddle example). This I believe is due to a deeper DOM tree (in fact, unnecessarily deep). The setTimeout let approach lets you do that.

解决方案

Use window.setTimeout() with some short unnoticeable delay to run slow function:

$(document).ready(function() {
    $('#enlace').click(function() {
        showImage();

        window.setTimeout(function() {
            sleepStupidly(4000);
            alert('now you do see it');
            hideImage();
        }, 50);
    });
});

Live demo

这篇关于强制DOM重绘与javascript按需的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆