[js點滴]JavaScript瀑布流實現技巧
阿新 • • 發佈:2019-01-08
基本結構
每一張圖片,外層是不可見的box,中間是可見的pic裝著img,要求盒子寬度固定。
距離控制
要使多個盒子間隙相同時,指定向左浮動並且設定box的上左內邊距即可,因為box不可見,實現的效果就類似於pic互相間隔開。
排列規則
先固定第一行,然後按照第一行的寬高,將後續圖片插入上一行最短的圖片下面。
獲取文件寬度和每個盒子寬度(此處取第一個盒子),然後相除獲得一行排列盒子的個數,將容器設定為盒子。
定位第一行盒子:top為0,left為單個盒子寬度×盒子順序的下標,將每一列盒子的高度儲存在一個數組中。
- 獲取第一行盒子高度的最小值(Math.min),然後依次比較確定是第幾個盒子,對於順序大於cnum的盒子,即第一行以後,位置即在第一行最短的盒子之下,定位為absolute,top值為最短盒子的高度,left值和上面的最短盒子一樣。
- 然後將盒子高度的陣列相應列數的高度值更新,繼續排列下一個盒子。
更新圖片
當滾動條拉到最後張圖片露出一半時,載入剩餘的圖片。
A 是最後一個 box 盒子的上邊距(offsetTop),B 是最後一個盒子高度的一半,C 是使用者拉動滾軸的長度(scrollTop),D 是頁面高度(clientHeight)。從上圖可以看出,當最後的 box 盒子沒出到一半時滿足
A+B>C+D
而當最後一個盒子出來一半時應該載入剩餘圖片了,此時A+B
適應瀏覽器寬度變化
一行能排列的盒子個數在文件剛載入完成時就固定了。當後續改變寬度時,需要隨之進行改變。
在window.onresize時呼叫waterfall函式。
<script type="text/javascript">
var arrH = [];//記錄每一列的高度
var k = 0;//用來記錄當前第幾個div的個數
createDiv(20)
change()
//1.建立DIV多少個div,通過函式的封裝
function createDiv(n) {
for (var i = 0; i < n; i++) {
k++;//每次呼叫for迴圈都對k進行++
var div = document.createElement("div" );
// 3.div的高度通過呼叫隨機函式進行建立
div.style.height = rndFn(100,300) + "px";
div.innerHTML = k;
document.body.appendChild(div);
}
}
//2.封裝一個隨機函式
function rndFn(min,max) {
return Math.round(Math.random()*(max-min)+min);
}
// 4.封裝函式,根據視窗大小制定div的排列方式
function change() {
//可視視窗的寬度
var winW = document.documentElement.clientWidth || window.innerWidth;
//獲取所有DIV
var aDiv = document.querySelectorAll("div");
//計算一行放多少列
var num = parseInt(winW/(aDiv[0].offsetWidth+10));
//計算空餘位置的一半
var center = (winW - (num*310-10))/2;
// 0 310 620 930
arrH = [];
for (var i = 0; i < aDiv.length; i++) {
// 前一排按照從左到右排列順序排列即可
if (i<num) {
aDiv[i].style.left = center+i*(300+10) + "px";
aDiv[i].style.top = 0;
//記錄每一列的高度
arrH[i] = aDiv[i].offsetHeight+10;
// arrH.push(aDiv[i].offsetHeight+10)
}else{
// 第二排開始就要開始查詢最小高度的div,然後在最小高度的div下插入新的元素
var min = findMin(arrH);
aDiv[i].style.left = center+min*(300+10) + "px";
aDiv[i].style.top = arrH[min] + "px";
arrH[min] += aDiv[i].offsetHeight + 10;
}
}
}
function findMin(arr) {
var min = arr[0];
var index = 0;
for (var i = 1; i < arr.length; i++) {
if (min>arr[i]) {
min = arr[i];
index = i;
}
}
return index;
}
window.onresize = function () {
change();
}
window.onscroll = function () {
var sTop = document.body.scrollTop || document.documentElement.scrollTop;
var winH = document.documentElement.clientHeight;
if (sTop+winH+20>=arrH[0]) {
createDiv(10);
change();
}
}
</script>