瀑布流的實(shí)現(xiàn)方式(原生js+jquery+css3)

字號:


    這篇文章主要為大家詳細(xì)介紹了原生js+jquery+css3實(shí)現(xiàn)瀑布流的相關(guān)代碼,三種實(shí)現(xiàn)瀑布流的方法,感興趣的小伙伴們可以參考一下
    前言
    項(xiàng)目需求要弄個(gè)瀑布流的頁面,用的是waterfall這個(gè)插件,感覺還是可以的,項(xiàng)目趕就沒自己的動手寫。最近閑來沒事,就自己寫個(gè)。大致思路理清楚,還是挺好實(shí)現(xiàn)的... 
    原生javascript版 
    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>瀑布流-javascript</title>
     <style>
     *{margin:0;padding:0;}
     #content{position: relative;margin:0 auto;}
     .box{padding:10px;float: left;}/*首行浮動,第二行開始絕對定位*/
     .box img{width: 180px;height:auto;display: block;}
     </style>
     <script>
     window.onload=function(){
      waterfall('content','box');
      //改變窗口大小時(shí),重新排列
      window.onresize = function(){
      waterfall('content','box');
      }
      //如果數(shù)據(jù)不夠,沒出現(xiàn)滾動條,自動加載數(shù)據(jù)
      var time=setInterval(function(){
      if(checkscrollside()){
       addDate();//插入數(shù)據(jù)
       waterfall('content','box');//加載完數(shù)據(jù)從新排列
      }else{
       clearInterval(time);
       window.onscroll=function(){
       if(checkscrollside()){
        addDate();
        waterfall('content','box');
       };
       }
      }
      },1000) 
     } 
     // 數(shù)據(jù)插入
     function addDate(){
      var dataInt=['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg'];//模擬數(shù)據(jù),也可以是對象
      var oParent = document.getElementById('content');
      for(var i=0;i<dataInt.length;i++){//循環(huán)插入數(shù)據(jù) 
      var oBox=document.createElement('div');
      oBox.className='box';
      oParent.appendChild(oBox);
      var oImg=document.createElement('img');
      oImg.src='./img/'+dataInt[i];
      oBox.appendChild(oImg);
      }
     }
     //主函數(shù)
     function waterfall(parentID,childClass){
      var oParent=document.getElementById(parentID);
      var arrBox=getClassObj(parentID,childClass);// getClassObj()獲取子class的數(shù)組
      var iBoxW=arrBox[0].offsetWidth;// 獲取瀑布流塊的寬度
      var num=Math.floor(document.documentElement.clientWidth/iBoxW);//計(jì)算窗口能容納幾列
      oParent.style.width=iBoxW*num+'px';//設(shè)置父級寬度
      var arrBoxH=[];//數(shù)組,用于存儲每列中的所有塊框相加的高度
      for(var i=0;i<arrBox.length;i++){//遍歷數(shù)組瀑布流 塊
      var boxH=arrBox[i].offsetHeight;//獲取當(dāng)前塊的高度
      if(i<num){
       arrBox[i].style.cssText="";//防止用戶改變窗口大小,到時(shí)樣式出錯(cuò)
       arrBoxH[i]=boxH; //第一行中的num個(gè)塊box 先添加進(jìn)數(shù)組arrBoxH
      }else{
       var minH=Math.min.apply(null,arrBoxH);//獲取數(shù)組arrBoxH中的最小值minH
       var minHIndex=getminHIndex(arrBoxH,minH);//遍歷數(shù)組獲取最小值minH的索引
       arrBox[i].style.position='absolute';//設(shè)置絕對位移
       arrBox[i].style.top=minH+'px';
       arrBox[i].style.left=minHIndex*iBoxW+'px';//也可以直接獲取arrBox[minHIndex].offsetLeft
       arrBoxH[minHIndex]+=arrBox[i].offsetHeight;//添加后,更新最小列高
      }
      }
     }
     //獲取子class的數(shù)組
     function getClassObj(parentID,childClass){
      var oParent=document.getElementById(parentID);
      var allChildObj=oParent.getElementsByTagName('*');//獲取父級下的所有子集
      var childObj=[];//創(chuàng)建一個(gè)數(shù)組 用于收集子元素
      for (var i=0;i<allChildObj.length;i++) {//遍歷子元素、判斷類別、壓入數(shù)組
      if (allChildObj[i].className==childClass){
       childObj.push(allChildObj[i]);
      }
      };
      return childObj;
     }
     //獲取數(shù)組最小值的索引
     function getminHIndex(arr,minH){
      for(var i in arr){
      if(arr[i]==minH){
       return i;
      }
      }
     }
     // 判斷滾動條是否到底部
     function checkscrollside(){
      var arrBox=getClassObj("content",'box');
      //獲取最后一個(gè)瀑布流塊的高度:距離網(wǎng)頁頂部(實(shí)現(xiàn)未滾到底就開始加載)
      var lastBoxH=arrBox[arrBox.length-1].offsetTop;
      var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//獲取滾動條卷走的高度
      var documentH=document.documentElement.clientHeight;//顯示頁面文檔的高
      return (lastBoxH<scrollTop+documentH)?true:false;//到達(dá)指定高度后 返回true,觸發(fā)waterfall()函數(shù)
     }
     </script>
    </head>
    <body>
     <div id="content">
     <div><img src="img/0.jpg"></div>
     <div><img src="img/1.jpg"></div>
     <div><img src="img/2.jpg"></div>
     <div><img src="img/3.jpg"></div>
     <div><img src="img/4.jpg"></div>
     <div><img src="img/5.jpg"></div>
     <div><img src="img/6.jpg"></div>
     <div><img src="img/7.jpg"></div>
     <div><img src="img/8.jpg"></div>
     <div><img src="img/9.jpg"></div>
     <div><img src="img/10.jpg"></div>
     </div>
    </body>
    </html>
    jquery版本 
    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>瀑布流-jquery</title>
     <style>
     *{margin:0;padding:0;}
     #content{position: relative;margin:0 auto;}
     .box{padding:10px;float: left;}
     .box img{width: 180px;height:auto;display: block;}
     </style>
     <script src="js/jquery-1.11.1.min.js"></script>
     <script>
     $(function(){
      waterfall();
      //改變窗口大小時(shí),重新排列
      $(window).resize(function(){
      waterfall();
      })
      //如果數(shù)據(jù)不夠,沒出現(xiàn)滾動條,自動加載數(shù)據(jù)
      var time=setInterval(function(){
      if(checkscrollside()){
       addDate();//插入數(shù)據(jù)
       waterfall();//加載完數(shù)據(jù)從新排列
      }else{
       clearInterval(time);
       $(window).scroll(function(){
       if(checkscrollside()){
        addDate();
        waterfall();
       };
       })
      }
      },1000) 
     }) 
     // 數(shù)據(jù)插入
     function addDate(){
      var dataInt=['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg'];//模擬數(shù)據(jù),也可以是對象
      var oParent = $('#content');
      for(var i=0;i<dataInt.length;i++){//循環(huán)插入數(shù)據(jù)
      oParent.append('<div><img src="./img/'+dataInt[i]+'"></div>'); 
      }
     }
     //主函數(shù)
     function waterfall(){
      var arrBox=$('#content').children('.box');// box對象
      var iBoxW=arrBox.eq(0).innerWidth();// 獲取瀑布流塊的寬度,注意width(),跟innerWidth()的區(qū)別
      var num=Math.floor($(window).width()/iBoxW);//計(jì)算窗口能容納幾列
      $('#content').css('width',iBoxW*num);//設(shè)置父級寬度
      var arrBoxH=[];//數(shù)組,用于存儲每列中的所有塊框相加的高度
      for(var i=0;i<arrBox.length;i++){//遍歷數(shù)組瀑布流 塊
      var boxH=arrBox.eq(i).innerHeight();//獲取當(dāng)前塊的高度
      if(i<num){
       arrBox.eq(i).attr('style','');//防止用戶改變窗口大小,到時(shí)樣式出錯(cuò)
       arrBoxH[i]=boxH; //第一行中的num個(gè)塊box 先添加進(jìn)數(shù)組arrBoxH
      }else{
       var minH=Math.min.apply(null,arrBoxH);//獲取數(shù)組arrBoxH中的最小值minH
       var minHIndex=$.inArray(minH,arrBoxH);//使用jquery提供的工具
       arrBox.eq(i).css({'position':'absolute','top':minH,'left':minHIndex*iBoxW});//設(shè)置定位
       arrBoxH[minHIndex]+=arrBox.eq(i).innerHeight();//添加后,更新最小列高
      }
      }
     }
     // 判斷滾動條是否到底部
     function checkscrollside(){
      var arrBox=$('#content').children('.box');
      //獲取最后一個(gè)瀑布流塊的高度:距離網(wǎng)頁頂部(實(shí)現(xiàn)未滾到底就開始加載)
      var lastBoxH=arrBox.eq(arrBox.length-1).offset().top;
      var scrollTop=$(window).scrollTop()//獲取滾動條卷走的高度
      var documentH=$(window).height();;//顯示頁面文檔的高
      return (lastBoxH<scrollTop+documentH)?true:false;//到達(dá)指定高度后 返回true,觸發(fā)waterfall()函數(shù)
     }
     </script>
    </head>
    <body>
     <div id="content">
     <div><img src="img/0.jpg"></div>
     <div><img src="img/1.jpg"></div>
     <div><img src="img/2.jpg"></div>
     <div><img src="img/3.jpg"></div>
     <div><img src="img/4.jpg"></div>
     <div><img src="img/5.jpg"></div>
     <div><img src="img/6.jpg"></div>
     <div><img src="img/7.jpg"></div>
     <div><img src="img/8.jpg"></div>
     <div><img src="img/9.jpg"></div>
     <div><img src="img/10.jpg"></div>
     </div>
    </body>
    </html>
    大致思路
     1.先讓第一行的浮動
     2.計(jì)算第一行的每個(gè)塊的高度
     3.遍歷第一行之后的每一個(gè)塊,逐個(gè)放在最小高度的下面
     4.加載數(shù)據(jù)插入最后,再重新計(jì)算 
    注意點(diǎn)
    a.原生js 
    1.定義了getClassObj()函數(shù)用于獲取class類的對象,方便調(diào)用??紤]了兼容性 getElementsByClassName  
    2.定義了getminHIndex()函數(shù)用戶獲取最小值的索引 
    3.設(shè)置塊與塊之間的距離最好用padding,這樣的話offsetHeight可以直接獲取得到高度。如果設(shè)置margin則得多加個(gè)外邊距的距離 
    4.代碼中設(shè)置了定時(shí)器加載數(shù)據(jù),其實(shí)可以省略,只要保證第一次加載的數(shù)據(jù)能滿屏就可以。如果沒出現(xiàn)滾動條的話onscroll事件是不會執(zhí)行到的。也就沒辦法加載數(shù)據(jù)了 
    5.代碼中的計(jì)算寬度也可以修改,設(shè)計(jì)的頁面是定寬的瀑布流的話。這里主要是做了響應(yīng)式的處理 
    var arrBox=getClassObj(parentID,childClass);// getClassObj()獲取子class的數(shù)組
    var iBoxW=arrBox[0].offsetWidth;// 獲取瀑布流塊的寬度
    var num=Math.floor(document.documentElement.clientWidth/iBoxW);//計(jì)算窗口能容納幾列
    oParent.style.width=iBoxW*num+'px';//設(shè)置父級寬度 
    6.每設(shè)置一塊位移,都要在列高的數(shù)組上增加數(shù)值,防止塊重疊 
    arrBox[i].style.position='absolute';//設(shè)置絕對位移
    arrBox[i].style.top=minH+'px';
    arrBox[i].style.left=minHIndex*iBoxW+'px';//也可以直接獲取arrBox[minHIndex].offsetLeft
    arrBoxH[minHIndex]+=arrBox[i].offsetHeight;//添加后,更新最小列高 
    b.jquery
    1.思路是跟js一樣的,只是jquery封裝了很多方法,讓我們簡便的就實(shí)現(xiàn)了
    2.注意width(),跟innerWidth()的區(qū)別。前者只能獲取寬度值(不包括補(bǔ)白padding) 
    css3版本
    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>瀑布流-css3</title>
     <style>
     *{margin:0;padding:0;}
     #content{margin:0 auto;position: relative;width:1200px;column-count:6;-moz-column-count:6;-webkit-column-count:6;}
     .box{padding:10px;width: 180px;}
     .box img{width: 180px;height:auto;display: block;}
     </style>
     <script>
     window.onload=function(){
      //如果數(shù)據(jù)不夠,沒出現(xiàn)滾動條,自動加載數(shù)據(jù)
      var time=setInterval(function(){
      if(checkscrollside()){
       addDate();//插入數(shù)據(jù)
      }else{
       clearInterval(time);
       window.onscroll=function(){
       if(checkscrollside()){
        addDate();
       };
       }
      }
      },1000) 
     } 
     // 數(shù)據(jù)插入
     function addDate(){
      var dataInt=['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg'];//模擬數(shù)據(jù),也可以是對象
      var oParent = document.getElementById('content');
      for(var i=0;i<dataInt.length;i++){//循環(huán)插入數(shù)據(jù) 
      var oBox=document.createElement('div');
      oBox.className='box';
      oParent.appendChild(oBox);
      var oImg=document.createElement('img');
      oImg.src='./img/'+dataInt[i];
      oBox.appendChild(oImg);
      }
     }
     //獲取子class的數(shù)組
     function getClassObj(parentID,childClass){
      var oParent=document.getElementById(parentID);
      var allChildObj=oParent.getElementsByTagName('*');//獲取父級下的所有子集
      var childObj=[];//創(chuàng)建一個(gè)數(shù)組 用于收集子元素
      for (var i=0;i<allChildObj.length;i++) {//遍歷子元素、判斷類別、壓入數(shù)組
      if (allChildObj[i].className==childClass){
       childObj.push(allChildObj[i]);
      }
      };
      return childObj;
     }
     // 判斷滾動條是否到底部
     function checkscrollside(){
      var arrBox=getClassObj("content",'box');
      //獲取最后一個(gè)瀑布流塊的高度:距離網(wǎng)頁頂部(實(shí)現(xiàn)未滾到底就開始加載)
      var lastBoxH=arrBox[arrBox.length-1].offsetTop;
      var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//獲取滾動條卷走的高度
      var documentH=document.documentElement.clientHeight;//顯示頁面文檔的高
      return (lastBoxH<scrollTop+documentH)?true:false;//到達(dá)指定高度后 返回true,觸發(fā)waterfall()函數(shù)
     }
     </script>
    </head>
    <body>
     <div id="content">
     <div><img src="img/0.jpg"></div>
     <div><img src="img/1.jpg"></div>
     <div><img src="img/2.jpg"></div>
     <div><img src="img/3.jpg"></div>
     <div><img src="img/4.jpg"></div>
     <div><img src="img/5.jpg"></div>
     <div><img src="img/6.jpg"></div>
     <div><img src="img/7.jpg"></div>
     <div><img src="img/8.jpg"></div>
     <div><img src="img/9.jpg"></div>
     <div><img src="img/10.jpg"></div>
     </div>
    </body>
    </html>
    注意點(diǎn)
    1.滾動加載還是得另外加js 
    2.加載的數(shù)據(jù),是豎向排列的。體驗(yàn)不是很友好 
    3.有兼容性問題,Internet Explorer 10 +
    以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助