瀑布流概念:又稱瀑布流式佈局,是比較流行的一種網站頁面佈局方式。視覺表現爲良莠不齊的多欄佈局,最先採用此佈局的是網站是Pinterest,後逐漸在國內流行。css
瀑布流原理:頁面容器內的多個高度不固定的div之間按照必定的間隔良莠不齊的無序浮動,鼠標滾動時不斷在容器內的尾部加載數據,且自動加載到空缺位置,不斷循環。json
優勢:數組
1.有效下降了界面複雜度,節省了空間:再也不須要臃腫複雜的頁面導航連接或者按鈕了; 瀏覽器
2.在觸屏設備上交互方式有更好的用戶體驗,經過向上滑動進行頁面滾動和數據加載,對操做的精準程度要求遠遠低於點擊按鈕或者連接;app
3.更高的參與度,使用戶能更好的專一於瀏覽而不是操做;ide
缺點:佈局
1.無限滾動只適用與特定類型產品中的某一類型,如某類微博信息,購物網站的某類商品,而不適用與通常的門戶網站,使用需斟酌;post
2.須要打造額外的js庫來保證頁面數據的加載和排列,而這在必定意義上增長了在網頁的性能和設備兼容等方面的問題。性能
js核心思路:網站
1.編寫方法:獲取容器內全部外層元素,存入數組;
2.編寫方法:計算容器內一行能夠承載多少個元素,方法:容器寬度/元素寬度,四捨五入向下取整;
3.編寫方法:把每一行中全部元素的高度值存入數組;
4.編寫方法:在高度值數組中找到最小高度值;
5.編寫方法:把第二行第一個元素定位到上一行全部元素中高度最低的元素下面,即設置該元素的top,left,position屬性;
6.編寫方法:重置當前高度值數組中的最小值;
7.編寫方法:從第二行第一個元素開始,遍歷每一個元素,用上述方法從新定位每一個元素的位置,把該事件綁定到頁面;
8.編寫方法:監聽鼠標事件,當前容器內最下面一個元素的offsetTop<瀏覽器可視高度+已滾動高度時,加載下一頁數據;
9.加載完以後,用上述方法從新定位新加載元素的位置;
JS實現:
window.onload = function(){ waterfall('main','box'); //模擬json數據 var dataJson = {'data': [{'src':'30.jpg'},{'src':'31.jpg'},{'src':'32.jpg'},{'src':'33.jpg'},{'src':'34.jpg'},{'src':'35.jpg'},{'src':'36.jpg'},{'src':'37.jpg'},{'src':'38.jpg'},{'src':'39.jpg'},{'src':'40.jpg'},{'src':'41.jpg'},{'src':'42.jpg'},{'src':'43.jpg'},{'src':'44.jpg'},{'src':'45.jpg'}]}; //監聽scroll事件 window.onscroll = function(){ var isPosting = false; if(checkScollSlide('main','box') && !isPosting){ var oParent = document.getElementById('main'); for(var i in dataJson.data){ isPosting = true; var oBox = document.createElement('div'); oBox.className = 'box'; oBox.innerHTML = '<div class="pic"><img src="./images/'+dataJson.data[i].src+'"></div>'; oParent.appendChild(oBox); } isPosting = false; waterfall('main','box'); } } } /* * parent 父元素id clsName 塊元素類*/ function waterfall(parent,clsName){ //獲取父元素 var oParent = document.getElementById(parent), //獲取全部box aBoxArr = oParent.getElementsByClassName(clsName), //單個box寬度 iBoxW = aBoxArr[0].offsetWidth, // 列數 cols = Math.floor(document.documentElement.clientWidth / iBoxW); oParent.style.cssText = 'width:'+iBoxW*cols+'px;margin:0 auto;'; //儲存全部的高度 var hArr = []; for(var i = 0; i < aBoxArr.length; i++){ if(i < cols){ hArr[i] = aBoxArr[i].offsetHeight; }else{ //獲取hArr最小值 var minH = Math.min.apply(null,hArr), // hArr最小值索引index minHIndex = getMinHIndex(hArr,minH); aBoxArr[i].style.cssText = 'position:absolute;top:'+minH+'px;left:'+aBoxArr[minHIndex].offsetLeft+'px;'; //添加元素以後更新hArr hArr[minHIndex] += aBoxArr[i].offsetHeight; } } } //獲取最小值索引 function getMinHIndex(arr,val){ for(var i in arr){ if(arr[i] == val){ return i; } } } //檢查是否知足加載數據條件,parent 父元素id clsName 塊元素類 function checkScollSlide(parent,clsName){ var oParent = document.getElementById(parent), aBoxArr = oParent.getElementsByClassName(clsName), // 最後一個box元素的offsetTop+高度的一半 lastBoxH = aBoxArr[aBoxArr.length - 1].offsetTop + aBoxArr[aBoxArr.length - 1].offsetHeight / 2, //兼容js標準模式和混雜模式 scrollTop = document.documentElement.scrollTop || document.body.scrollTop, height = document.documentElement.clientHeight || document.body.clientHeight; return lastBoxH < scrollTop + height ? true : false; }