你的位置:首页 > Java教程

[Java教程]瀑布流布局学习


  1. 特点:等宽不等高。
  2. 实现方式:Javascript/Jquery/CSS3多栏布局。
  3. 样例网站:花瓣网-->分类(http://huaban.com/)

一、JS实现瀑布流

      index.html:页面结构

     

 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4   <meta charset="UTF-8"> 5   <title>瀑布流布局</title> 6   <link rel="stylesheet" href="styles/layout.css"> 7 </head> 8 <body> 9   <div id="main">10     <div class="box"><div class="pic"><img src="../waterFall/pic/0.jpg" alt=""></div></div>11     <div class="box"><div class="pic"><img src="../waterFall/pic/1.jpg" alt=""></div></div>12     <div class="box"><div class="pic"><img src="../waterFall/pic/2.jpg" alt=""></div></div>13     <div class="box"><div class="pic"><img src="../waterFall/pic/3.jpg" alt=""></div></div>14     <div class="box"><div class="pic"><img src="../waterFall/pic/4.jpg" alt=""></div></div>15     <div class="box"><div class="pic"><img src="../waterFall/pic/5.jpg" alt=""></div></div>16     <div class="box"><div class="pic"><img src="../waterFall/pic/6.jpg" alt=""></div></div>17     <div class="box"><div class="pic"><img src="../waterFall/pic/7.jpg" alt=""></div></div>18     <div class="box"><div class="pic"><img src="../waterFall/pic/8.jpg" alt=""></div></div>19     <div class="box"><div class="pic"><img src="../waterFall/pic/9.jpg" alt=""></div></div>20     <div class="box"><div class="pic"><img src="../waterFall/pic/10.jpg" alt=""></div></div>21     <div class="box"><div class="pic"><img src="../waterFall/pic/11.jpg" alt=""></div></div>22     <div class="box"><div class="pic"><img src="../waterFall/pic/12.jpg" alt=""></div></div>23     <div class="box"><div class="pic"><img src="../waterFall/pic/13.jpg" alt=""></div></div>24     <div class="box"><div class="pic"><img src="../waterFall/pic/14.jpg" alt=""></div></div>25     <div class="box"><div class="pic"><img src="../waterFall/pic/15.jpg" alt=""></div></div>26     <div class="box"><div class="pic"><img src="../waterFall/pic/16.jpg" alt=""></div></div>27     <div class="box"><div class="pic"><img src="../waterFall/pic/17.jpg" alt=""></div></div>28     <div class="box"><div class="pic"><img src="../waterFall/pic/18.jpg" alt=""></div></div>29     <div class="box"><div class="pic"><img src="../waterFall/pic/19.jpg" alt=""></div></div>30     <div class="box"><div class="pic"><img src="../waterFall/pic/20.jpg" alt=""></div></div>31     <div class="box"><div class="pic"><img src="../waterFall/pic/21.jpg" alt=""></div></div>32     <div class="box"><div class="pic"><img src="../waterFall/pic/22.jpg" alt=""></div></div>33     <div class="box"><div class="pic"><img src="../waterFall/pic/23.jpg" alt=""></div></div>34     <div class="box"><div class="pic"><img src="../waterFall/pic/24.jpg" alt=""></div></div>35     <div class="box"><div class="pic"><img src="../waterFall/pic/25.jpg" alt=""></div></div>36     <div class="box"><div class="pic"><img src="../waterFall/pic/26.jpg" alt=""></div></div>37     <div class="box"><div class="pic"><img src="../waterFall/pic/27.jpg" alt=""></div></div>38     <div class="box"><div class="pic"><img src="../waterFall/pic/28.jpg" alt=""></div></div>39     <div class="box"><div class="pic"><img src="../waterFall/pic/29.jpg" alt=""></div></div>40     <div class="box"><div class="pic"><img src="../waterFall/pic/30.jpg" alt=""></div></div>41     <div class="box"><div class="pic"><img src="../waterFall/pic/31.jpg" alt=""></div></div>42     <div class="box"><div class="pic"><img src="../waterFall/pic/32.jpg" alt=""></div></div>43     <div class="box"><div class="pic"><img src="../waterFall/pic/33.jpg" alt=""></div></div>44     <div class="box"><div class="pic"><img src="../waterFall/pic/34.jpg" alt=""></div></div>45     <div class="box"><div class="pic"><img src="../waterFall/pic/35.jpg" alt=""></div></div>46     <div class="box"><div class="pic"><img src="../waterFall/pic/36.jpg" alt=""></div></div>47     <div class="box"><div class="pic"><img src="../waterFall/pic/37.jpg" alt=""></div></div>48     <div class="box"><div class="pic"><img src="../waterFall/pic/38.jpg" alt=""></div></div>49     <div class="box"><div class="pic"><img src="../waterFall/pic/39.jpg" alt=""></div></div>50     <div class="box"><div class="pic"><img src="../waterFall/pic/40.jpg" alt=""></div></div>51     <div class="box"><div class="pic"><img src="../waterFall/pic/41.jpg" alt=""></div></div>52     <div class="box"><div class="pic"><img src="../waterFall/pic/42.jpg" alt=""></div></div>53     <div class="box"><div class="pic"><img src="../waterFall/pic/43.jpg" alt=""></div></div>54   </div>55   <script src="scripts/waterfall.js"></script>56 </body>57 </html>

View Code

      layout.css:页面元素样式

 1 *{ 2   pdding:0; 3   margin:0; 4 } 5 div#main{ 6   position: relative; 7 } 8 div.box{ 9   padding:15px 0 0 15px;10   float: left;11 }12 div.pic{13   padding:10px;14   border:1px solid #ccc;15   border-radius:5px;16   box-shadow: 0 0 5px #ccc;17 }18 .pic img{19   height:auto;20   width:165px;21 }

View Code

      waterfall.js

 1 window.onload=function(){ 2   waterFall('main','box'); 3   //模拟后台相应数据json 4   var dataInt={ 5     "data": 6     [ 7     {"src":"0.jpg"}, 8     {"src":"1.jpg"}, 9     {"src":"2.jpg"},10     {"src":"3.jpg"},11     {"src":"4.jpg"},12     {"src":"5.jpg"},13     {"src":"6.jpg"}14     ]15   }16   window.onscroll=function(){17     if(checkScrollSlide){18       //将数据块渲染到当前页面的尾部19      var oParent=document.getElementById("main");20      for(var i=0;i<dataInt.data.length;i++){21        var oBox=document.createElement("div");22        oBox.className="box";23        oParent.appendChild(oBox);24        var oPic=document.createElement("div");25        oPic.className="pic";26        oBox.appendChild(oPic);27        var img=document.createElement("img");28        img.setAttribute("src",dataInt.data[i]);29        img.src="pic/"+dataInt.data[i].src;30        oPic.appendChild(img);31      }32      dataInt=null;//清空数据块,防止无限加载33      waterFall('main','box');//对页面新元素进行布局渲染34     }35   }36 }37 function waterFall(parent,box){38   //将main下的class为box的所有元素取出来39   var oParent=document.getElementById(parent);40   var oBoxs=getByClass(oParent,box);41   console.log(oBoxs.length);42   //计算整个页面显示的列数(页面宽/box宽)43   var oBoxW=oBoxs[0].offsetWidth;44   // console.log(oBoxW);45   var cols=Math.floor(document.documentElement.clientWidth/oBoxW);46   // console.log(cols);47   //设置main的宽48   oParent.style.cssText="width:"+oBoxW*cols+"px;margin:0 auto;"49   var hArr=[];//存放每列高度的数组50   for(var i=0;i<oBoxs.length;i++){51     if(i<cols){52       hArr.push(oBoxs[i].offsetHeight);53     }else{54       var minH=Math.min.apply(null,hArr);//获取当前数组最小高度值55       // console.log(minH);56       var index=getMinhIndex(hArr,minH);//获取数组最小高度的索引57       //console.log(index);58       oBoxs[i].style.position="absolute";//将之后的图片依次绝对定位59       oBoxs[i].style.top=minH+"px";60       oBoxs[i].style.left=index*oBoxW+"px";//计算新图片所在的位置并赋值61       hArr[index]+=oBoxs[i].offsetHeight;//变化数组列的高度值,因为加上了一张图片62     }63     //console.log(hArr);64   }65 66 }67 //根据class获取元素68 function getByClass(parent,clsName){69  var boxArr=new Array(),//用来存储获取到的所有class为box的元素70    oElements=parent.getElementsByTagName("*");71    for(var i=0;i<oElements.length;i++){72      if(oElements[i].className==clsName){73         boxArr.push(oElements[i]);74       }75     }76   return boxArr;77 }78 function getMinhIndex(arr,val){79   for(var i=0;i<arr.length;i++){80     if(arr[i]==val){81       return i;82     }83   }84 85 }86 //检测是否具备滚动条加载数据块条件87 function checkScrollSlide(){88   var oParent=document.getElementById("main");89   var oBoxs=getByClass(oParent,"box");90   var lastBoxH=oBoxs[oBoxs.length-1].offsetTop+Math.floor(oBoxs[oBoxs.length-1].offsetHeight/2);91   var scrollTop=document.body.scrollTop||document.documentElement.scrollTop;//混杂模式和标准模式下的scrollTop获取92   //console.log(scrollTop);93   var height=document.body.clientHeight||document.documentElement.clientHeight;//混杂模式和标准模式下的浏览器窗口高度获取94   return (lastBoxH<scrollTop+height)?true:false;//检测最后一个box高度是否小于滚动高度+窗口高度,返回布尔值95 96 }

 二、JQuery

       

 1 $( window ).on( "load", function(){ 2   waterfall('main','pin'); 3   var dataInt={'data':[{'src':'1.jpg'},{'src':'2.jpg'},{'src':'3.jpg'},{'src':'4.jpg'}]}; 4   window.onscroll=function(){ 5     if(checkscrollside()){ 6       $.each( dataInt.data, function( index, value ){ 7         var $oPin = $('<div>').addClass('pin').appendTo( $( "#main" ) ); 8         var $oBox = $('<div>').addClass('box').appendTo( $oPin ); 9         $('<img>').attr('src','./images/' + $( value).attr( 'src') ).appendTo($oBox);10       });11       waterfall();12     };13   }14 });15 16 /*17   parend 父级id18   pin 元素id19 */20 function waterfall(parent,pin){21   var $aPin = $( "#main>div" );22   var iPinW = $aPin.eq( 0 ).width();// 一个块框pin的宽23   var num = Math.floor( $( window ).width() / iPinW );//每行中能容纳的pin个数【窗口宽度除以一个块框宽度】24   //oParent.style.cssText='width:'+iPinW*num+'px;ma rgin:0 auto;';//设置父级居中样式:定宽+自动水平外边距25   $( "#main" ).css({26     'width:' : iPinW * num,27     'margin': '0 auto'28   });29 30   var pinHArr=[];//用于存储 每列中的所有块框相加的高度。31 32   $aPin.each( function( index, value ){33     var pinH = $aPin.eq( index ).height();34     if( index < num ){35       pinHArr[ index ] = pinH; //第一行中的num个块框pin 先添加进数组pinHArr36     }else{37       var minH = Math.min.apply( null, pinHArr );//数组pinHArr中的最小值minH38       var minHIndex = $.inArray( minH, pinHArr );39       $( value ).css({40         'position': 'absolute',41         'top': minH + 15,42         'left': $aPin.eq( minHIndex ).position().left43       });44       //数组 最小高元素的高 + 添加上的aPin[i]块框高45       pinHArr[ minHIndex ] += $aPin.eq( index ).height() + 15;//更新添加了块框后的列高46     }47   });48 }49 50 function checkscrollside(){51   var $aPin = $( "#main>div" );52   var lastPinH = $aPin.last().get(0).offsetTop + Math.floor($aPin.last().height()/2);//创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)53   var scrollTop = $( window ).scrollTop()//注意解决兼容性54   var documentH = $( document ).height();//页面高度55   return (lastPinH < scrollTop + documentH ) ? true : false;//到达指定高度后 返回true,触发waterfall()函数56 }

三、CSS多栏布局

     

 1 .container{ 2   -webkit-column-width:160px; 3   -moz-column-width:160px;  4    -webkit-column-gap:5px; 5    -moz-column-gap:5px; 6 } 7  8  9 /*数据块 砖块*/10 11 .container div{width:160px;12         margin:4px 0;}

【css3和js实现方法比较】--css3方式--1:不需要计算,浏览器自动计算,只需设置1列宽,性能高2:列宽随着浏览器宽口大小进行改变,用户体验不好;3:图片排序按照垂直顺序排列,打乱图片显示顺序4.图片加载还是需要js--js方式--js实现的瀑布流不会有上面的缺点,但是性能相对要差!