瀑布流布局:JS+绝对定位

开发 前端
现在很多网站博客都流行瀑布流布局,你是否也想了解是如何实现的呢?本文将给大家详细的介绍。

绝对定位方式的瀑布流布局:

一、布局

1、包围块框的容器:

  1. <div id="main"> 
  2.     ... ...  
  3. <div> 

2、一个块框:

  1. <div class="pin"> 
  2.     <div class="box"> 
  3.         <img src="./images/g (1).jpg"/> 
  4.     </div> 
  5. </div> 

3、初始化第一行/5个块框:

  1. .pin{  
  2.         padding15px 0 0 15px;  
  3.         floatleft;}  
  4.     .box{  
  5.         padding10px;  
  6.         border:1px solid #ccc;}  
  7.     .box img{  
  8.         width:192px;  
  9.         height:auto;} 

效果:

二、思路:

1、设置父级main的样式:水平居中。

2、设置每个块框pin的样式:绝对定位。

3、设置窗口滚动事件的监听函数:读取数据添加块框。

JS实现:

1-①:获取父级oParent:

1-②:创建函数getClassObj()-通过父级id和块框类名-获取包含块框的数组。

  1. var oParent=document.getElementById('main');// 父级对象  
  2. var aPin=getClassObj(oParent,pin);// 获取存储块框pin的数组aPin  
  3. var num=Math.floor(document.documentElement.clientWidth/aPin[0].offsetWidth);//获取-每行中能容纳的块框个数-num【窗口宽度除以一个块框宽度】  
  4.  
  5. arent.style.cssText='width:'+iPinW*num+'px;margin:0 auto;';//用cssText属性为父级main添加居中样式:定宽+自动水平外边距  
  1. function getClassObj(parent,className){  
  2.         var obj=parent.getElementsByTagName('*');//获取 父级的所有子集  
  3.         var pinS=[];//创建一个数组 用于存储类为className的元素  
  4.         for (var i=0;i<obj.length;i++) {//遍历子集、判断类名、压入数组  
  5.             if (obj[i].className==className)  
  6.                 pinS.push(obj[i]);  
  7.         };  
  8.         return pinS;} 

2-①:创建数组pinHArr-用于存储每一列高度;

2-②:for语句遍历每个块框aPin[i],将前num个块框赋值给数组pinHArr,对超出一行能容纳的块框数num的块框绝对定位。

2-③:用创建函数getminHIndex()-返回一个数组中的最小值

  1. var pinHArr=[];//用于存储 每列中的所有块框相加的高度【随着列数的不同此数组的length也随之改变】  
  2.     for(var i=0;i<aPin.length;i++){//遍历数组aPin的每个块框元素  
  3.         var pinH=aPin[i].offsetHeight;//获取数组aPin的第i个块框的可见宽offsetHeight  
  4.         if(i<num){//  
  5.             pinHArr[i]=pinH; //第一行中的num个块框aPin 先添加进数组pinHArr  
  6.         }else{  
  7.             var minH=Math.min.apply(null,pinHArr);//计算数组pinHArr中的最小值minH  
  8.             var minHIndex=getminHIndex(pinHArr,minH);//通过创建的getminHIndex()-获取最小值minH在数组pinHArr中的索引minHIndex  
  9.             aPin[i].style.position='absolute';//设置绝对位移  
  10.             aPin[i].style.top=minH+'px';  
  11.             aPin[i].style.left=aPin[minHIndex].offsetLeft+'px';//数组 最小高元素的高 + 添加上的aPin[i]块框高  
  12.             pinHArr[minHIndex]+=aPin[i].offsetHeight;//更新添加块框后的列高  
  13.         }  
  14.     } 
  1. function getminHIndex(arr,minH){  
  2.     for(var i in arr){  
  3.         if(arr[i]==minH)return i;  
  4.     }  

3:设置窗口滚动事件的监听函数:读取数据添加块框。

  1. var dataInt={'data':[{'src':'g (1).jpg'},{'src':'g (9).jpg'},{'src':'g (2).jpg'},{'src':'g (4).jpg'}]};//一个临时的数据对象  
  2.     //下面定义窗口滚动事件监听函数  
  3.     window.onscroll=function(){  
  4.         if(checkscrollside()){  
  5.         var oParent=document.getElementById('main');// 父级对象  
  6.         for(var i=0;i<dataInt.data.length;i++){  
  7.             var oPin=document.createElement('div'); //创建添加 元素节点pin  
  8.             oPin.className='pin';                   //添加 类名 name属性  
  9.             oParent.appendChild(oPin);              //创建添加 子节点box  
  10.             var oBox=document.createElement('div');  
  11.             oBox.className='box';  
  12.             oPin.appendChild(oBox);  
  13.             var oImg=document.createElement('img');//创建添加 子节点img  
  14.             oImg.src='./images/'+dataInt.data[i].src;  
  15.             oBox.appendChild(oImg);  
  16.         }  
  17.         waterfall('main','pin');//将①②封装成函数waterfall(),将添加的节点添加到添加和定位到文档中。  
  18.         };  
  19.     } 
  1. function checkscrollside(){  
  2.         var oParent=document.getElementById('main');  
  3.         var aPin=getClassObj(oParent,'pin');  
  4.         var lastPinH=aPin[aPin.length-1].offsetTop+Math.floor(aPin[aPin.length-1].offsetHeight/2);//创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)  
  5.         var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//注意解决兼容性  
  6.         var documentH=document.documentElement.clientHeight;//窗口高度  
  7.         return (lastPinH<scrollTop+documentH)?true:false;//到达指定高度后 返回true,触发waterfall()函数  
  8.     } 

三、最终效果:

四、总结:此为让自己梳理一下思路,表达不太仔细连贯,仅供参考。

#p#

五、完成后的html文件和js文件:

html:index.html

  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.  <meta name="anchor" content="who care?" /> 
  6.  <script type="text/javascript" src="waterfall.js"/></script> 
  7.    
  8.  <title></title> 
  9.  <style type="text/css"> 
  10.      *{padding: 0;margin:0;}  
  11.      #main{  
  12.          position: relative;  
  13.      }  
  14.      .pin{  
  15.          padding: 15px 0 0 15px;  
  16.          float:left;  
  17.      }  
  18.      .box{  
  19.          padding: 10px;  
  20.          border:1px solid #ccc;  
  21.          box-shadow: 0 0 6px #ccc;  
  22.          border-radius: 5px;  
  23.      }  
  24.      .box img{  
  25.          width:162px;  
  26.          height:auto;  
  27.      }  
  28.  </style> 
  29.  </head> 
  30.  <body> 
  31.  <div id="main"> 
  32.      <div class="pin"> 
  33.          <div class="box"> 
  34.              <img src="./images/g (1).jpg"/> 
  35.          </div> 
  36.      </div> 
  37.      <div class="pin"> 
  38.          <div class="box"> 
  39.              <img src="./images/g (2).jpg"/> 
  40.          </div> 
  41.      </div> 
  42.      <div class="pin"> 
  43.          <div class="box"> 
  44.              <img src="./images/g (3).jpg"/> 
  45.          </div> 
  46.      </div> 
  47.      <div class="pin"> 
  48.          <div class="box"> 
  49.              <img src="./images/g (4).jpg"/> 
  50.          </div> 
  51.      </div> 
  52.      <div class="pin"> 
  53.          <div class="box"> 
  54.              <img src="./images/g (5).jpg"/> 
  55.          </div> 
  56.      </div> 
  57.  </div> 
  58.  </body> 
  59.  </html> 

js:waterfall.js

  1. window.onload=function(){
  2. waterfall('main','pin');  
  3.      var dataInt={'data':[{'src':'g (1).jpg'},{'src':'g (9).jpg'},{'src':'g (2).jpg'},{'src':'g (4).jpg'}]};  
  4.        
  5.      window.onscroll=function(){  
  6.          if(checkscrollside()){  
  7.          var oParent=document.getElementById('main');// 父级对象  
  8.          for(var i=0;i<dataInt.data.length;i++){  
  9.              var oPin=document.createElement('div'); //添加 元素节点  
  10.              oPin.className='pin';                   //添加 类名 name属性  
  11.              oParent.appendChild(oPin);              //添加 子节点  
  12.              var oBox=document.createElement('div');  
  13.              oBox.className='box';  
  14.              oPin.appendChild(oBox);  
  15.              var oImg=document.createElement('img');  
  16.              oImg.src='./images/'+dataInt.data[i].src;  
  17.              oBox.appendChild(oImg);  
  18.          }  
  19.          waterfall('main','pin');  
  20.          };  
  21.      }  
  22.        
  23.  }  
  24.  /*  
  25.          parend 父级id  
  26.          pin 元素id  
  27.  */ 
  28.  function waterfall(parent,pin){  
  29.      var oParent=document.getElementById(parent);// 父级对象  
  30.      var aPin=getClassObj(oParent,pin);// 获取存储块框pin的数组aPin  
  31.      var iPinW=aPin[0].offsetWidth;// 一个块框pin的宽  
  32.      var num=Math.floor(document.documentElement.clientWidth/iPinW);//每行中能容纳的pin个数【窗口宽度除以一个块框宽度】  
  33.      oParent.style.cssText='width:'+iPinW*num+'px;ma rgin:0 auto;';//设置父级居中样式:定宽+自动水平外边距  
  34.    
  35.      var pinHArr=[];//用于存储 每列中的所有块框相加的高度。  
  36.      for(var i=0;i<aPin.length;i++){//遍历数组aPin的每个块框元素  
  37.          var pinH=aPin[i].offsetHeight;  
  38.          if(i<num){  
  39.              pinHArr[i]=pinH; //第一行中的num个块框pin 先添加进数组pinHArr  
  40.          }else{  
  41.              var minH=Math.min.apply(null,pinHArr);//数组pinHArr中的最小值minH  
  42.              var minHIndex=getminHIndex(pinHArr,minH);  
  43.              aPin[i].style.position='absolute';//设置绝对位移  
  44.              aPin[i].style.top=minH+'px';  
  45.              aPin[i].style.left=aPin[minHIndex].offsetLeft+'px';  
  46.              //数组 最小高元素的高 + 添加上的aPin[i]块框高  
  47.              pinHArr[minHIndex]+=aPin[i].offsetHeight;//更新添加了块框后的列高  
  48.          }  
  49.      }  
  50.  }  
  51.      /****  
  52.          *通过父级和子元素的class类 获取该同类子元素的数组  
  53.          */ 
  54.      function getClassObj(parent,className){  
  55.          var obj=parent.getElementsByTagName('*');//获取 父级的所有子集  
  56.          var pinS=[];//创建一个数组 用于收集子元素  
  57.          for (var i=0;i<obj.length;i++) {//遍历子元素、判断类别、压入数组  
  58.              if (obj[i].className==className){  
  59.                  pinS.push(obj[i]);  
  60.              }  
  61.          };  
  62.          return pinS;  
  63.      }  
  64.      /****  
  65.          *获取 pin高度 最小值的索引index  
  66.          */ 
  67.      function getminHIndex(arr,minH){  
  68.          for(var i in arr){  
  69.              if(arr[i]==minH){  
  70.                  return i;  
  71.              }  
  72.          }  
  73.      }  
  74.    
  75.    
  76.      function checkscrollside(){  
  77.          var oParent=document.getElementById('main');  
  78.          var aPin=getClassObj(oParent,'pin');  
  79.          var lastPinH=aPin[aPin.length-1].offsetTop+Math.floor(aPin[aPin.length-1].offsetHeight/2);//创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)  
  80.          var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//注意解决兼容性  
  81.          var documentH=document.documentElement.clientHeight;//页面高度  
  82.          return (lastPinH<scrollTop+documentH)?true:false;//到达指定高度后 返回true,触发waterfall()函数  
  83.      } 

原文链接:http://www.cnblogs.com/slowsoul/archive/2013/02/10/2909746.html

责任编辑:林师授 来源: 博客园
相关推荐

2024-08-19 14:01:00

2021-08-09 07:26:33

瀑布流布局代码

2010-09-14 16:57:29

DIV绝对定位CSS

2012-05-02 13:53:00

JavaScript

2010-09-01 14:02:27

绝对定位浮动CSS

2010-09-07 15:38:42

CSS绝对定位浮动

2010-08-16 11:28:02

DIV

2010-09-06 11:17:19

CSS相对定位CSS绝对定位

2010-08-26 16:48:48

DIV绝对定位相对定位

2009-12-29 10:06:09

WPF Canvas

2010-09-10 11:32:23

CSS绝对定位CSS相对定位

2010-09-10 12:40:06

CSS相对定位CSS绝对定位

2021-01-29 10:57:57

新基建政策解读智慧物流

2024-09-03 17:04:15

前端算法布局

2010-08-25 14:45:57

CSS绝对定位

2010-09-10 13:07:51

CSS DIV绝对定位CSS DIV固定定位

2010-08-17 11:10:16

DIV+CSS

2010-09-14 16:39:26

CSS DIV相对定位CSS DIV绝对定位

2022-06-28 22:17:52

浏览器底层css

2010-08-16 08:54:48

DIVCSS
点赞
收藏

51CTO技术栈公众号