JQUERY瀑布流

jquery瀑布流布局:现在很流行的一种网页布局效果,瀑布流,随意、洒脱,个性十足,一种代表时尚潮流的网页设计风格。

http://www.sitejs.cn/code/down/jsdmview/waterfall/这里也有一个瀑布流效果,但个人觉得效果不好。它的排版原理是先统计n列,然后生成n个DIV。然后统计这排DIV的高度来分配图片的方法。开始加载感觉不出问题来。如果窗口变化几次排序就会乱了,而且打乱原有节点的排序,还有它是直接修改了原有节点结构,渲染过程中很卡甚至卡死。我觉得应该保持原有节点不要更改,只修改图片的div坐标位置达到排序功能即可。

先看看DEMO:http://down.scscms.com/scs/waterfall/index.html

========================javascript脚本======================

<script>
    $(function(){waterfall(".cell")});
    function waterfall(cls){
        if(!$(cls).length) return;//没有元素
        var con={
            obj:null,//图片div对象
            l:0, //总共数量
            w:214,//列宽
            s:10,//列间距
            list:0, //多少列
            h:1, //外div的高
            arr:[],//最后一排数组
            state:"loading" //状态 loading:加载图片中,ajax:正在发生ajax请求,finish:完成任务,load_resize:加裁过程中窗口变化(记录起来,加载完后处理),resize:执行了窗口变化,reset:窗口变化排序中再次重排
        };
        con.obj=$(cls);//图片div对象
        con.l=con.obj.size();//统计共有多少个图片div
        con.list=Math.floor($("#container").width()/(con.w+con.s));//统计共有多少列
        fall_pic(0);
        $(window).resize(function(){
            var w=Math.floor($("#container").width()/(con.w+con.s));//重新统计共有多少列
            if(w!=con.list){
                //窗口变化造成列数发生了变化
                if("loading|load_resize|ajax".indexOf(con.state)!=-1){
                    //如果正在加载中,需要加载完后再执行重排
                    con.state="load_resize";
                }else{
                    //已经排完或者执行重排过程
                    con.list=w;
                    con.h=1;
                    if("finish"==con.state){
                        con.state="resize";//执行重排
                        fall_pic(0);
                    }else{
                        con.state="reset";//重排中的重排
                        //因为已经在重排过程中,不能再次调用函数。但可让编号再从0开始
                    }
                }
            }
        }).scroll(function(){
                    if("finish"==con.state){
                        var top=con.obj.last().offset().top;//最后一张图片的坐标
                        var scrollTop=document.documentElement.scrollTop||document.body.scrollTop||0;//滚动条距离
                        var windowHeight=document.documentElement.clientHeight||document.body.clientHeight||0;//窗口高度
                        if(windowHeight+scrollTop>=top){
                            con.state="ajax";//当滚动条拉到看到最后一张图片时
                            var html='';//实现案例中此改成ajax请求json或html,每次请求只增加一排
                            for(var i=con.l;i<con.l+con.list;i++){
                                html+='<div class="cell"><img src="http://cued.xunlei.com/demos/publ/img/P_'+('00'+i%162).slice(-3)+'.jpg" /><h3>'+i+' AJAX加载</h3><p>JQUERY瀑布流原理:每次排版取前一排最低的位置接着排,窗口改变后先计算一下列数有没有发生变化,变化后才重排。当下拉滚动条达到最后一个DIV的顶部时请求ajax生成新的图片插到底部执行继排功能。</p></div>';
                            }
                            $("#container").append(html);
                            con.obj=$(cls);//更新对象
                            var _i=con.l;//记录加载前的最后一个编号
                            con.l=con.obj.size();//统计现在共有多少张图片
                            fall_pic(_i);//接着加载前最一张图片排序;
                        }
                    }
                });
        function fall_pic(n){
            if("reset"==con.state){
                n=0;//处理重排中窗口再次变化
                con.state="resize";
            }
            //以下con.state可能存在的值为 loading,ajax,load_resize,resize
            if(n<con.l){
                var obj=con.obj.eq(n);//获取对象
                var x= 0,y=0;//对象坐标值
                if(n<con.list){
                    x=n*(con.w+con.s);//如果是第一排,y=0,x=宽度+列间距
                    con.arr[n]=obj;//把最后一排对象组成数组供后面用
                }else{
                    var _i=0;//查一下最后一排哪张图片的底部离顶部最高,然后在其后面插入新图片
                    for(var i= 0;i<con.list;i++){
                        var _top=con.arr[i].position().top+con.arr[i].outerHeight(true)+con.s;
                        if(0==y)y = _top;
                        if(y>_top){
                            _i=i;
                            y=_top;
                            x=i*(con.w+con.s);
                        }
                    }
                    con.arr[_i]=obj;//替换数组
                }
                if("resize"==con.state){
                    //如果是窗口变化,属于重排,不需要预加载图片
                    if(y==obj.position().top&&x==obj.position().left){                        
                        n++;//原位不变的跳过排序动画
                        fall_pic(n);
                    }else{
                        obj.animate({top:y,left:x},"fast",function(){
                            var _h=obj.position().top+obj.outerHeight(true);
                            if(_h>con.h){
                                con.h=_h;
                                $("#container").stop().animate({height:_h},"fast");//设置外框高
                            }
                            n++;
                            fall_pic(n);
                        });
                    }
                }else{
                    var img=new Image();
                    img.onload=function(){
                        obj.css({top:y,left:x}).fadeIn("slow",function(){
                            var _h=obj.position().top+obj.outerHeight(true);
                            if(_h>con.h){
                                con.h=_h;
                                $("#container").stop().animate({height:_h},"fast");//设置外框高
                            }
                            n++;
                            fall_pic(n);
                        });
                    };
                    img.onerror=function(){
                        //加载失败就替换图片,并省去设置外围div的高
                        obj.css({top:y,left:x}).fadeIn("slow",function(){
                            n++;
                            fall_pic(n);
                        }).find("img").attr("src","error.jpg");
                    };
                    img.src=obj.find("img").attr("src");
                }
            }else{
                setTimeout(function(){
                    if("load_resize"==con.state&&con.list!=Math.floor($("#container").width()/(con.w+con.s))){
                        con.state="finish";//如果是在预加载图片时改变了窗口大小需要重排的情况
                        $(window).resize();
                    }else{
                        con.state="finish";//延时一下,以防自动不断触发scroll
                    }
                },300)
            }
        }
    }
</script>

出处:http://bbs.csdn.net/topics/390417656?page=1#post-394145542

posted on 2013-04-08 16:51  马晓锋  阅读(250)  评论(0编辑  收藏  举报