javacript 實現瀑布流原理和效果, 滾動加載圖片【圖文解析 附源碼】

先科普下瀑布流吧html

瀑布流,又稱瀑布流式佈局。是比較流行的一種網站頁面佈局,視覺表現爲良莠不齊的多欄佈局,隨着頁面滾動條向下滾動,這種佈局還會不斷加載數據塊並附加至當前尾部。最先採用此佈局的網站是Pinterest,逐漸在國內流行開來。國內大多數清新站基本爲這類風格,像美麗說、淘寶網都有使用。數組

這是我實現的一個效果,就是怎麼滾動都加載不玩。就跟瀑布同樣流啊流!app

這裏的實現方式咱們只說Js實現方法函數

實現原理:佈局

對容器中已有數據塊元素進行第一次計算1 容器總寬度 2 列寬度  3 最小列數 ,獲得列數後,用一個數組存放盒子全部高度,找出最小高度。以後根據序列號更新高度;看着有些拗口,實現起來就很簡單了。網站

對於滾動加載:即滾動到哪一個高度後,須要去加載數據,其實這個就是列的最小高度值,這樣當前滾動值和最小高度值比較一下便可判斷出來,是否要觸發加載數據;就是寫一個函數,用來判斷是否達到加載圖片條件,若是達到,就開始加載。好比得到最後一張圖片的offsetTop,可視區高度,滾動距離,也就是當圖片的offsetTop小於可視區高度和滾動距離之和的狀況下,此時就應該加載了,不過條件能夠隨便定,也能夠等滾動到圖片的一半時候在觸發加載條件,如圖所示:spa

先上HTML CSS代碼rest

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>waterfall</title>
  6     <script src="script.js"></script>
  7     <style>
  8         * {
  9             margin: 0;
 10             padding: 0;
 11         }
 12         body {
 13             background: yellow;
 14         }
 15         #container {
 16 
 17         }
 18         #container .pin {
 19             padding-left: 15px;
 20             padding-top: 15px;
 21             float: left;
 22         }
 23         #container .div-box {
 24             float: left;
 25             border: 1px solid #ccc;
 26             box-shadow: 0 0 5px #bbb;
 27             background: #fff;
 28             padding: 12px;
 29             border-radius: 9px;
 30         }
 31         #container .div-box img {
 32             width: 300px;
 33         }
 34         #container .div-box p {
 35             text-align: center;
 36             font-size: 20px;
 37             font-weight: bold;
 38             color: red;
 39         }
 40     </style>
 41     <script>
 42         
 43     </script>
 44 </head>
 45 <body>
 46     <div id="container">
 47         <div class="pin">
 48             <div class="div-box">
 49                 <img src="img/1.jpg" alt="">
 50                 <p>白超華-博客園</p>
 51             </div>
 52         </div>
 53         <div class="pin">
 54             <div class="div-box">
 55                 <img src="img/2.jpg" alt="">
 56                 <p>白超華-博客園</p>
 57             </div>
 58         </div>
 59         <div class="pin">
 60             <div class="div-box">
 61                 <img src="img/3.jpg" alt="">
 62                 <p>白超華-博客園</p>
 63             </div>
 64         </div>
 65         <div class="pin">
 66             <div class="div-box">
 67                 <img src="img/4.jpg" alt="">
 68                 <p>白超華-博客園</p>
 69             </div>
 70         </div>
 71         <div class="pin">
 72             <div class="div-box">
 73                 <img src="img/5.jpg" alt="">
 74                 <p>白超華-博客園</p>
 75             </div>
 76         </div>
 77         <div class="pin">
 78             <div class="div-box">
 79                 <img src="img/6.jpg" alt="">
 80                 <p>白超華-博客園</p>
 81             </div>
 82         </div>
 83         <div class="pin">
 84             <div class="div-box">
 85                 <img src="img/7.jpg" alt="">
 86                 <p>白超華-博客園</p>
 87             </div>
 88         </div>
 89         <div class="pin">
 90             <div class="div-box">
 91                 <img src="img/8.jpg" alt="">
 92                 <p>白超華-博客園</p>
 93             </div>
 94         </div>
 95         <div class="pin">
 96             <div class="div-box">
 97                 <img src="img/9.jpg" alt="">
 98                 <p>白超華-博客園</p>
 99             </div>
100         </div>
101         <div class="pin">
102             <div class="div-box">
103                 <img src="img/10.jpg" alt="">
104                 <p>白超華-博客園</p>
105             </div>
106         </div>
107         <div class="pin">
108             <div class="div-box">
109                 <img src="img/1.jpg" alt="">
110                 <p>白超華-博客園</p>
111             </div>
112         </div>
113         <div class="pin">
114             <div class="div-box">
115                 <img src="img/2.jpg" alt="">
116                 <p>白超華-博客園</p>
117             </div>
118         </div>
119         <div class="pin">
120             <div class="div-box">
121                 <img src="img/3.jpg" alt="">
122                 <p>白超華-博客園</p>
123             </div>
124         </div>
125         <div class="pin">
126             <div class="div-box">
127                 <img src="img/4.jpg" alt="">
128                 <p>白超華-博客園</p>
129             </div>
130         </div>
131         <div class="pin">
132             <div class="div-box">
133                 <img src="img/5.jpg" alt="">
134                 <p>白超華-博客園</p>
135             </div>
136         </div>
137         <div class="pin">
138             <div class="div-box">
139                 <img src="img/6.jpg" alt="">
140                 <p>白超華-博客園</p>
141             </div>
142         </div>
143     </div>
144 </body>
145 </html>

JS代碼,每行都有註釋code

 1 window.onload = function(){
 2     var data = {                    //模擬後臺數據 的一個JSON格式的文件
 3         "data":[
 4             {"src":"1.jpg"},
 5             {"src":"2.jpg"},
 6             {"src":"3.jpg"},
 7             {"src":"4.jpg"},
 8             {"src":"5.jpg"},
 9         ]
10     };
11     window.onscroll = function(){
12         if(checkScroll()){          //判斷是否具有滾動加載得條件
13             var oParent = document.getElementById('container');
14             for(var i=0; i<data.data.length; i++){
15                 var div1 = document.createElement('div');  //建立div元素
16                 div1.className = 'pin';                    //設置class
17                 oParent.appendChild(div1);
18                 var div2 = document.createElement('div');//建立div元素
19                 div2.className = 'div-box';
20                 div1.appendChild(div2);
21                 var imgs = document.createElement('img');//建立img元素
22                 imgs.style.width = '300px';
23                 imgs.src = 'img/'+data.data[i].src;    //設置讀取路徑
24                 div2.appendChild(imgs);
25                 var p = document.createElement('p');//建立p元素
26                 p.innerHTML = '白超華-博客園';
27                 div2.appendChild(p);
28             }
29             waterfall('container','pin');     //--注意 別忘了這句,當滾動時候就執行
30         }
31     }
32     waterfall('container','pin');
33 }
34 function waterfall(parent, box){
35     var oParent = document.getElementById(parent);//獲取父級對象
36     var aBox = getByClass(oParent,box);//獲取全部class爲pin的盒子的集合
37     var boxWidth = aBox[0].offsetWidth;//獲取一個盒子的寬
38     var pageWidth = document.body.clientWidth||document.documentElement.clientWidth;//獲取可視區寬
39     var cols = Math.floor(pageWidth/boxWidth);//得到列數
40     var arrH = [];//用於存放盒子的高
41 
42     for(var i=0; i<aBox.length; i++){
43         if(i<cols){//當小於第一列個數的時候
44             arrH.push(aBox[i].offsetHeight);
45         } else {
46             var minH = Math.min.apply(null,arrH);//獲得數組中盒字的最小高度minH;
47             var index = getMinIndex(arrH,minH);
48 
49             aBox[i].style.position = 'absolute';//設置絕對定位
50             aBox[i].style.top = minH+'px';//設置top,就是最小高度
51             aBox[i].style.left = aBox[0].offsetWidth*index+'px';//設置left,就是一個盒子的寬*index索引數
52             arrH[index]+=aBox[i].offsetHeight; //更新新添加盒字後的列高
53         }
54     }
55 }
56 //經過父級獲取class
57 function getByClass(parent, classname){
58     var aClass = parent.getElementsByTagName('*');
59     var arr = [];
60 
61     for(var i=0; i<aClass.length; i++){
62         if(aClass[i].className == classname){
63             arr.push(aClass[i]);
64         }
65     }
66     return arr;
67 }
68 //最小值的索引index
69 function getMinIndex(arr,val){
70     for( i in arr){
71         if(arr[i] == val){
72             return i;
73         }
74     }
75 }
76 //
77 function checkScroll(){
78     var oParent = document.getElementById('container');
79     var aBox = getByClass(oParent,'pin');
80     var lastBoxHeight = aBox[aBox.length-1].offsetTop;// 當滾到到這個距離時候就開始加載
81     var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//兼容的滾動距離
82     var documentHeight = document.documentElement.clientHeight; //頁面高度
83     if(lastBoxHeight<scrollTop+documentHeight){
84         return true;
85     }
86 }
相關文章
相關標籤/搜索