js原生寫一個瀑布流

瀑布流特點:

1. 瀑布流元素寬度相同,高度不同
2. 滾動頁面時,在頁面高度最小處插入元素

效果圖:
在這裏插入圖片描述
話不多說,直接上代碼
css:

	   * {
            margin: 0;
            padding: 0;
        }
        .box {
            float: left;
            padding: 0 5px;
        }
        .pic {
            padding: 2px;
            border-radius: 5px;
            box-sizing: border-box;
        }
        .pic img {
            width: 200px;
        }

html:
/* box元素可以適當多複製一些,撐起scrollTop事件 */

	<div id="main">

        <div class="box">
            <div class="pic"><img src="./img/set3/1.jpg" alt=""></div>
        </div>
        <div class="box">
            <div class="pic"><img src="./img/set3/2.jpg" alt=""></div>
        </div>
        <div class="box">
            <div class="pic"><img src="./img/set3/3.jpg" alt=""></div>
        </div>
        <div class="box">
            <div class="pic"><img src="./img/set3/4.jpg" alt=""></div>
        </div>
        <div class="box">
            <div class="pic"><img src="./img/set3/5.jpg" alt=""></div>
        </div>
        <div class="box">
            <div class="pic"><img src="./img/set3/6.jpg" alt=""></div>
        </div>
        <div class="box">
            <div class="pic"><img src="./img/set3/7.jpg" alt=""></div>
        </div>
        <div class="box">
            <div class="pic"><img src="./img/set3/8.jpg" alt=""></div>
        </div>
        <div class="box">
            <div class="pic"><img src="./img/set3/9.jpg" alt=""></div>
        </div>
        <div class="box">
            <div class="pic"><img src="./img/set3/10.jpg" alt=""></div>
        </div>
        <div class="box">
            <div class="pic"><img src="./img/set3/11.jpg" alt=""></div>
        </div>
    </div>

js:

/* 聲明需要的變量
oParent  父級容器
boxW     單個盒子寬度
col      屏幕一排顯示的列數
minHArr  各列數中,距離頂部的高度 
*/
var oParent, boxW, col, minHArr;
window.onload = function () {
    oParent = document.getElementById('main');   //獲取父容器
    boxW =  getAllBox(oParent, 'box')[0].clientWidth;  //獲取單個盒子寬度
   // 獲取屏幕中存在的列數
    col = Math.floor(document.documentElement.clientWidth / boxW);
    waterFall(oParent, 'box');  //頁面元素重排
    window.onscroll = function () {
        // 滾動時做極值判斷,是否到達底部
        if (isBottom(oParent, 'box')) {
            var fakerArr = fakerData(); //要加載的數據
            for (var i = 0; i < fakerArr.length; i++) {
               //動態創建dom結構,添加到頁面中
                var oBox = document.createElement('div');
                oBox.className = 'box';
                var oPic = document.createElement('div');
                oPic.className = 'pic';
                var oImg = document.createElement('img');
                oImg.src = fakerArr[i].img;
                oPic.appendChild(oImg);
                oBox.appendChild(oPic);
                oParent.appendChild(oBox);
            }
           waterFall(oParent, 'box'); //頁面元素重排
        }
    
    }
    // 改變屏幕寬度時,重新獲取列數
    window.onresize = function () {
        col = Math.floor(document.documentElement.clientWidth / boxW);
        waterFall(oParent, 'box'); //頁面元素重排
    }
}

function waterFall(oParent, className = 'box') {
    var oBoxs = getAllBox(oParent, className);
    minHArr = [];  // 存儲各列數距離頂部的高度 
    for (var i = 0; i < oBoxs.length; i++) {
        if (i < col) {  // 第一排,爲float元素,不改變位置,獲取盒子高度
            minHArr.push(oBoxs[i].clientHeight)
        } else {
            // 第二排時,取第一排最小高度值,定位過去
            var minH = Math.min.apply(null, minHArr); // 此時一排最小高度
            var minIndex = getLocationIndex(minHArr, minH); // 數組中的索引值
            oBoxs[i].style.position = 'absolute'; //絕對定位 
            oBoxs[i].style.top = minH + 'px';  // 設置top值,爲數組最小高度
            // 設置top值,索引 * 盒子寬度
            oBoxs[i].style.left = minIndex * boxW + 'px'; 
            // 元素定位排版後,重新設置此列高度值
            minHArr[minIndex] = minH + oBoxs[i].clientHeight;
        }
    }
}
// 不直接用getElementsByClassName, 可能存在兼容性問題
function getAllBox(oParent, className = 'box') {
        var allArr = oParent.getElementsByTagName('*');
        var boxArr = [];
        for (var i = 0; i < allArr.length; i++) {
            if (allArr[i].className === className) {
                boxArr.push(allArr[i])
            }
        }
        return boxArr
}
// 獲取數組索引值, indexOf個別瀏覽器不兼容
function getLocationIndex(arr, item) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === item) {
            return i
        }
    }
}

function isBottom(oParent, className = 'box') {
    // 重新獲取頁面中box數量
    var oBoxs = getAllBox(oParent, className);
    /* 獲取最後一盒子頭部距離頂部距離(最後一盒子offsetTop爲上一排盒子中距離頂部最小值) */
    var lastBoxH = oBoxs[oBoxs.length - 1].offsetTop; 
    // 獲取滾動條捲去的高度
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    // 獲取瀏覽器屏幕寬度
    var clientH = document.documentElement.clientHeight || document.body.clientHeight;
    //當能看到最後一盒子頭部時,返回true
    return  scrollTop + clientH >= lastBoxH ? true : false
}


function fakerData() {
    return [{
            img: './img/set3/1.jpg'
        },
        {
            img: './img/set3/2.jpg'
        },
        {
            img: './img/set3/3.jpg'
        },
        {
            img: './img/set3/4.jpg'
        },
        {
            img: './img/set3/5.jpg'
        },
        {
            img: './img/set3/6.jpg'
        },
        {
            img: './img/set3/7.jpg'
        },
        {
            img: './img/set3/8.jpg'
        },
        {
            img: './img/set3/9.jpg'
        },
        {
            img: './img/set3/10.jpg'
        },
        {
            img: './img/set3/11.jpg'
        }

    ]
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章