瀑布流

学习了某大神的瀑布流布局:

基本原理:(下图出自残手,请见谅它的不完美)

黑框:document

蓝色框:container容器

红色框:浏览器可视区域

黄线:A..offsetTop+Math.floor(A.offsetHeight/2)

绿线:document.documentElement.scrollTop

1.所有图片等宽不等长;

2.图片加载时机:当可视区域超过最后一张图片的1/2即可记载新内容:A..offsetTop+Math.floor(A.offsetHeight/2)>document.documentElement.scrollTop+document.documentElement.clientHeight

 

HTML+CSS

  1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  5 <link href='demo.css' type='text/css' rel='stylesheet'>
  6 <script src='demo.js' type='text/javascript'></script>
  7 <title瀑布流</title>
  8 <style>
  9 *{
 10     margin:0;
 11     padding: 0;
 12 }
 13 #content{
 14     position: relative;
 15 }
 16 
 17 div.blc{
 18 
 19     padding: 15px 0 0 15px;
 20     float: left;
 21 }
 22 div.pic{
 23     padding:10px;
 24     border: 1px solid #ccc;
 25     border-radius: 5px;
 26     box-shadow: 0 0 5px #ccc;   /*设置阴影,水平和垂直方向上偏移值为0,阴影模糊度为5px;*/
 27 }
 28 .pic img{
 29     height: auto;
 30     width: 236px;
 31 }
 32 
 33 </style>
 34 </head>
 35 <body>
 36     <div id='content'>
 37         <div class='blc'>
 38             <div class='pic'><img src='images/1.jpg'></div>
 39         </div>
 40         <div class='blc'>
 41             <div class='pic'><img src='images/2.jpg'></div>
 42         </div>
 43         <div class='blc'>
 44             <div class='pic'><img src='images/3.jpg'></div>
 45         </div>
 46         <div class='blc'>
 47             <div class='pic'><img src='images/4.jpg'></div>
 48         </div>
 49         <div class='blc'>
 50             <div class='pic'><img src='images/5.jpg'></div>
 51         </div>
 52         <div class='blc'>
 53             <div class='pic'><img src='images/6.jpg'></div>
 54         </div>
 55         <div class='blc'>
 56             <div class='pic'><img src='images/7.jpg'></div>
 57         </div>
 58         <div class='blc'>
 59             <div class='pic'><img src='images/8.jpg'></div>
 60         </div>
 61         <div class='blc'>
 62             <div class='pic'><img src='images/9.jpg'></div>
 63         </div>
 64         <div class='blc'>
 65             <div class='pic'><img src='images/10.jpg'></div>
 66         </div>
 67         <div class='blc'>
 68             <div class='pic'><img src='images/11.jpg'></div>
 69         </div>
 70         <div class='blc'>
 71             <div class='pic'><img src='images/12.jpg'></div>
 72         </div>
 73         <div class='blc'>
 74             <div class='pic'><img src='images/13.jpg'></div>
 75         </div>
 76         <div class='blc'>
 77             <div class='pic'><img src='images/14.jpg'></div>
 78         </div>
 79         <div class='blc'>
 80             <div class='pic'><img src='images/15.jpg'></div>
 81         </div>
 82         <div class='blc'>
 83             <div class='pic'><img src='images/16.jpg'></div>
 84         </div>
 85         <div class='blc'>
 86             <div class='pic'><img src='images/17.jpg'></div>
 87         </div>
 88         <div class='blc'>
 89             <div class='pic'><img src='images/18.jpg'></div>
 90         </div>
 91         <div class='blc'>
 92             <div class='pic'><img src='images/19.jpg'></div>
 93         </div>
 94         <div class='blc'>
 95             <div class='pic'><img src='images/20.jpg'></div>
 96         </div>
 97         <div class='blc'>
 98             <div class='pic'><img src='images/21.jpg'></div>
 99         </div>
100         <div class='blc'>
101             <div class='pic'><img src='images/22.jpg'></div>
102         </div>
103         <div class='blc'>
104             <div class='pic'><img src='images/23.jpg'></div>
105         </div>
106         <div class='blc'>
107             <div class='pic'><img src='images/24.jpg'></div>
108         </div>
109         <div class='blc'>
110             <div class='pic'><img src='images/25.jpg'></div>
111         </div>
112         <div class='blc'>
113             <div class='pic'><img src='images/26.jpg'></div>
114         </div>
115         <div class='blc'>
116             <div class='pic'><img src='images/27.jpg'></div>
117         </div>
118         <div class='blc'>
119             <div class='pic'><img src='images/31.jpg'></div>
120         </div>
121         <div class='blc'>
122             <div class='pic'><img src='images/29.jpg'></div>
123         </div>
124         <div class='blc'>
125             <div class='pic'><img src='images/30.jpg'></div>
126         </div>
127     </div>
128 </body>
129 </html>
View Code

JAVASCRIPT

window.onload=function(){
    waterfall('content','blc');



    //Json模仿后台数据
    var dataInt={"data":[{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'},{"src":'4.jpg'},{"src":'5.jpg'},{"src":'6.jpg'},{"src":'7.jpg'},{"src":'8.jpg'},{"src":'9.jpg'},{"src":'10.jpg'}]}
    window.onscroll=function(){
        if(checkScrollSlide){
            //加载数据
            var oparent=document.getElementById('content')

            for(var i=0; i<dataInt.data.length; i++){   
                var oblc=document.createElement('div')    //创建模块div节点
                oblc.className='blc';
                oparent.appendChild(oblc);
                var opic=document.createElement('div')    //创建图片外层div节点
                opic.className='pic';
                oblc.appendChild(opic)
                var oimg=document.createElement('img')    //创建img节点
                oimg.src="images/"+dataInt.data[i].src    
                opic.appendChild(oimg)

            }
            waterfall('content','blc');    //新加载的图片块执行瀑布流操作
        }
    }

}


//实现瀑布流的函数
function waterfall(parent,box){
    //取出所有的class为blc的元素
    var oparent=document.getElementById(parent);           //参数不用加引号
    var oblc=getClass(oparent,box);
    // console.log(oblc.length)


    //计算页面显示的列数
    var oblcW=oblc[0].offsetWidth;           //每个图片块的宽度
    var cols=Math.floor(document.documentElement.clientWidth/oblcW)    //列数=屏幕宽度/图片块宽度,需要向下取整
    //设置content的宽度和居中,cssText可以集中设置样式
    oparent.style.cssText='Width:'+oblcW*cols+'px;margin:0 auto' ;

    //创建一个存放美列高度的数组
    var hArray=[];
    for(i=0; i<oblc.length;i++){
        if(i<cols){                                           //i<cols的元素都是第一列元素
            hArray.push(oblc[i].offsetHeight)                                        //储存每列的高,开始时是第一列每一张图片的高
        }else{                                                //开始第二列
            var minH=Math.min.apply(null,hArray)              //找出最小列的高度,Math.min方法不能存放数组,只能存放一组数,所有用apply方法更改函数或方法中this的指向
            var index=getminhIndex(hArray,minH);
            oblc[i].style.position='absolute';                            
            oblc[i].style.top=minH+'px';                        //将高度设为最短列的高度
            oblc[i].style.left=oblc[index].offsetLeft+'px';
            hArray[index]+=oblc[i].offsetHeight;           //每一列添加一个新元素后,该列高度=原来高度+新元素高度
        }
    }
    
}

//根据className获取元素
function getClass(parent,clsName){
    var classArray=[];    //用来储存取到的className元素
    var allElements=parent.getElementsByTagName('*');
    for(i=0;i<allElements.length;i++){
        if(allElements[i].className==clsName){                
            classArray.push(allElements[i])
        }
    }
    return classArray;
}

//取列高最小的列的索引
function getminhIndex(arr,val){                    //传递俩个参数,一个是列高数组,一个是列高最小值
    for(var i in arr){              
        if(arr[i]==val){                        //返回列高最小值在数组中的索引,即列位
            return i;
        }
    }
}

//是否加载的判断函数
function checkScrollSlide(){
    var oparent=document.getElementById('content');
    var oblc=getClass(oparent,'blc');
    //加载条件:最后一个图像块的的offsetTop+自身高度的一半 < 滚动条的滚动量+屏幕的可视高度
    var lastblcH=oblc[oblc.length-1].offsetTop+Math.floor(oblc[oblc.length-1].offsetHeight/2);  
    var scrollTop=document.body.scrollTop ||document.documentElement.scrollTop;  //混杂模式、标准模式;兼容
    var height=document.body.clientHeight||document.documentElement.clientHeight;     //浏览器可视区域
    return  (lastblcH<scrollTop+height)?true:false;  
}

 jQuery实现:

$(window).on('load',function(){
    waterfall('content','blc');
    var dataInt={"data":[{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'},{"src":'4.jpg'},{"src":'5.jpg'},{"src":'6.jpg'},{"src":'7.jpg'},{"src":'8.jpg'},{"src":'9.jpg'},{"src":'10.jpg'}]}
    
    $(window).on('scroll',function(){

        if(checkScrollSlide){
            $.each(dataInt.data,function(key,value){
                var obox=$('<div>').addClass('blc').appendTo($('#content'));
                var opic=$('<div>').addClass('pic').appendTo($(obox));
                //这里value为js原生对象,无法使用jQuery方法,要转化为jQuery方法
                var oimg=$('<img>').attr('src','images/'+$(value).attr('src')).appendTo($(opic));
                //console.log(oimg.attr('src'))
                //console.log($(value).attr('src'))
                //console.log(value);
            })
            waterfall();
        }
        
    })

})
    

    


function waterfall(parent,box){
    var oparent = $('#content');
    var boxs = $('div .blc');
    //计算列数
    var boxW = boxs.eq(0).outerWidth();
    var h = boxs.eq(0).outerHeight();

    
    
    var clientW = $(window).width();
    var lists = Math.floor(clientW/boxW);
    $('#content').width(lists*boxW).css('margin','0 auto');
    //遍历,取出列高
    var hArray=[];
    boxs.each(function(index,value){
        var h = boxs.eq(index).outerHeight();
        //console.log(h)
        if(index<lists){
            hArray[index]=h
            //console.log(hArray)
        }else{
            var minH = Math.min.apply(null,hArray);
            var minHindex = $.inArray(minH,hArray);  //获取数组索引值,第一个参数为值,第二个参数为数组名
            //console.log(value)  value为DOM对象,无法使用jQuery方法,要转化为jQuery方法
            $(value).css({
                'position':'absolute',
                'left':minHindex*boxW+'px',
                'top':minH+'px'
            })
            hArray[minHindex]+=boxs.eq(index).outerHeight();
        }
        

    })

    //console.log(hArray)

}


function checkScrollSlide(){
    var lastblc = $('div .blc').last();
    var lastblcH = lastblc.offset().top+Math.floor(lastblc.outerHeight()/2);
    console.log(lastblcH)
    var scrollTop = $(window).scrollTop();
    var clientH = $(window).height();
    return (lastblcH<scrollTop+clientH)?true:false;
}

 

posted @ 2015-04-24 12:29  Bigdots  阅读(401)  评论(0编辑  收藏  举报