zoukankan      html  css  js  c++  java
  • javascript的setTimeout以及setInterval休眠问题。

    前端码农们在做项目中时候,必定不可少的需要做到轮播效果。但是有些特殊的需求,比如:

     

     需要做到第一个容器内容轮播滚动之后,第二个容器内部再轮播滚动,再第三个容器内容轮播滚动。

    这时候我的一开始的思路是:每个容器都看成一个单独的轮播效果,既然是依次的滚动就设定滚动开始时间差,三个setTimeout()分别延迟差。

     HTML 代码:

    <div id="warp">
            <div class="items">
                <ul class="island s1">
                    <li>111</li>
                    <li>222</li>
                    <li>333</li>
                </ul>
            </div>
            <div class="items">
                <ul class="island s2">
                    <li>444</li>
                    <li>555</li>
                    <li>666</li>
                </ul>
            </div>
            <div class="items">
                <ul class="island s3">
                    <li>777</li>
                    <li>888</li>
                    <li>999</li>
                    <li>000</li>
                </ul>
            </div>
     </div> 

      

     CSS 代码:

    .items{height: 18px;overflow: hidden;margin-bottom: 10px;border-bottom: 1px dashed #999;} 

    JAVASCRIPT 代码:(基于jquery的实现)

    var uls = $("#warp").find(".island"),
        lh = uls.find('li').height(),
        size  = uls.size(),
        Global=[];//全局变量


    uls.each(function(i,el){
        $(el).find('li').first().clone(true).appendTo($(el));

    });

    /*动画效果*/
    function animates(i){
       Global[i]==undefined&&(Global[i]=0);
        Global[i]++;
        _els =uls.eq(i);
        var len = _els.find('li').length;
        _els.animate({"marginTop":-Global[i]*lh+"px"},600,function(){
            if(Global[i] == len-1){
                Global[i]=0;
                _els.css({"margin-top":"0px"});
            }
        }); 
    };
    function interval(i){
        setInterval(function(){
            animates(i)
        },5000);
    };
    for(var x=0;x<size;x++){
        (function(x){
            setTimeout(function(){
                interval(x);
            },650+x*650);
        })(x)
    }; 

    一开始的时候我发现都是OK的,但是当我切换到别的页面,或者暂时最小化的时候,轮播就变得杂乱无章。这个问题困扰我很久,到公司请教

    大牛同事,他说可能是 setInterval休眠问题导致。

    经过仔细的查阅资料以及实践,发现当页面最小化时候或者切换网页浏览其他网页等情况时, setInterval是会暂时进入“休眠”状态,但是并不是不执行程序,它会把需要执行的操作放在队列中 ,等到下次窗口一打开的一瞬间把队列里面的全部执行,由于程序处理太快我们大部分时候并没有注意到这个问题。但是你去看所有网站的轮播效果,

    假设现在你轮播的是第四张大图,下次打开时候播放的可能是任意的。

    再分析上面的程序:

    我们让程序分别过650ms, 1300ms,1950ms执行如果窗口一直是这个是本窗口,也就是没有进行休眠。程序可以照常执行。

    如果窗口最小化,程序进入休眠,会把队列中的操作在很快时间内一起执行,所以程序一下子就乱啦。

    那如何解决这个问题呢?还是想了啦jquery的animate,如果在动画animate的回调中进行递归,进入下次的轮播。那不就完美解决!!

    让我们来看程序:

     JAVASCRIPT代码:

    var uls = $("#warp").find(".island"),
        lh = uls.find('li').height(),
        size  = uls.size(),
        i = 0;

    uls.each(function(i,el){
        $(el).find('li').first().clone(true).appendTo($(el));
    });
    function animates(i){
        var ul = $('.items').eq(i).find('ul');
        if(!ul){return false;}
        var count = parseInt(ul.attr("count-role")||0);
        count++;
        var len = ul.find('li').length;
        ul.animate({"marginTop":-count*lh+"px"},600,function(){
            if(count == len-1){
                count=0;
                ul.css({"margin-top":"0px"});
            }
            ul.attr("count-role",count);
            animates(++i);
        }); 
    };
    function interval(){
        setInterval(function(){
            animates(i)
        },5000);
    };
    interval() 

    这样就完美解决了这个问题。

    我猜想可能由于浏览器的特殊性,它的资源有限。所以采用这个策略,也是可以理解的。


  • 相关阅读:
    Direct2D教程(二)来看D2D世界中的Hello,World
    绕任意轴旋转
    XPDM vs WDDM
    也谈杨辉三角形
    用DirectX实现粒子系统(一)
    Alpha混合(一)Vertex Alpha
    几何变换详解
    用DirectX实现粒子系统(三)
    Alpha混合(二)Material Alpha
    Direct2D教程(五)复合图形
  • 原文地址:https://www.cnblogs.com/heimanba/p/3847981.html
Copyright © 2011-2022 走看看