11

问题的标题表达了我认为我的具体案例背后的终极问题。

我的情况:在点击处理程序中,我想在繁忙的功能开始之前使图像可见(“加载”动画)。然后我想在功能完成后再次使其不可见。而不是我所期望的,我意识到图像永远不会变得可见。我猜这是由于浏览器等待处理程序结束,然后才能进行任何重绘(我相信这有很好的性能原因)。

代码(也在这个小提琴中: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 方法可以让你做到这一点。

4

5 回答 5

7

使用 JQueryshowhide回调(或其他显示淡入/淡出的方式)。

http://jsfiddle.net/JLmh4/3/

$(document).ready(function () {
    $('#enlace').click(function () {
        var kitty = $('#kitty');


        // see: http://unixpapa.com/js/sleep.html
        function sleepStupidly(usec) {
            var endtime = new Date().getTime() + usec;
            while (new Date().getTime() < endtime);
        }

        kitty.show(function () {

            // 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.hide();
        });
    });
});
于 2013-06-01T18:17:56.807 回答
5

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

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

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

现场演示

于 2013-06-01T18:33:46.667 回答
4

要强制重绘,可以使用 offsetHeight 或 getComputedStyle()。

var foo = window.getComputedStyle(el, null);

或者

var bar = el.offsetHeight;

"el" 是一个 DOM 元素

于 2016-08-05T19:21:24.900 回答
0

我不知道这是否适用于您的情况(因为我没有测试过),但是在使用 JavaScript/jQuery 操作 CSS 时,有时需要强制重绘特定元素以使更改生效。

这是通过简单地请求一个 CSS 属性来完成的。

在您的情况下,我会尝试kitty.position().left;在弄乱setTimeout.

于 2014-11-02T08:26:23.130 回答
0

对我有用的是设置以下内容:

$(element).css('display','none'); 

之后你可以做任何你想做的事,最终你想做的事:

$(element).css('display','block');
于 2017-06-27T07:06:19.653 回答