1. 程式人生 > >[js點滴]JavaScript瀑布流實現技巧

[js點滴]JavaScript瀑布流實現技巧

基本結構

每一張圖片,外層是不可見的box,中間是可見的pic裝著img,要求盒子寬度固定。

距離控制

要使多個盒子間隙相同時,指定向左浮動並且設定box的上左內邊距即可,因為box不可見,實現的效果就類似於pic互相間隔開。

排列規則

先固定第一行,然後按照第一行的寬高,將後續圖片插入上一行最短的圖片下面。

  1. 獲取文件寬度和每個盒子寬度(此處取第一個盒子),然後相除獲得一行排列盒子的個數,將容器設定為盒子。

  2. 定位第一行盒子:top為0,left為單個盒子寬度×盒子順序的下標,將每一列盒子的高度儲存在一個數組中。

  3. 獲取第一行盒子高度的最小值(Math.min),然後依次比較確定是第幾個盒子,對於順序大於cnum的盒子,即第一行以後,位置即在第一行最短的盒子之下,定位為absolute,top值為最短盒子的高度,left值和上面的最短盒子一樣。
  4. 然後將盒子高度的陣列相應列數的高度值更新,繼續排列下一個盒子。

更新圖片

當滾動條拉到最後張圖片露出一半時,載入剩餘的圖片。

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>