++ eat end log 自動 獲取 left 容器 load

瀑布流布局詳解

瀑布流概念:又稱瀑布流式布局,是比較流行的一種網站頁面布局方式。視覺表現為參差不齊的多欄布局,最早采用此布局的是網站是Pinterest,後逐漸在國內流行。

瀑布流原理:頁面容器內的多個高度不固定的div之間按照一定的間隔參差不齊的無序浮動,鼠標滾動時不斷在容器內的尾部加載數據,且自動加載到空缺位置,不斷循環。

優點:

1.有效降低了界面復雜度,節省了空間:不再需要臃腫復雜的頁面導航鏈接或者按鈕了;

2.在觸屏設備上交互方式有更好的用戶體驗,通過向上滑動進行頁面滾動和數據加載,對操作的精準程度要求遠遠低於點擊按鈕或者鏈接;

3.更高的參與度,使用戶能更好的專註於瀏覽而不是操作;

缺點:

1.無限滾動只適用與特定類型產品中的某一類型,如某類微博信息,購物網站的某類商品,而不適用與一般的門戶網站,使用需斟酌;

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;
}

瀑布流布局