天天看點

瀑布流案例

<!DOCTYPE html>
<html >

<head>
  <meta charset="UTF-8">
  <title>瀑布流布局</title>
  <link rel="stylesheet" href="css/index.css" target="_blank" rel="external nofollow" >
<style>
*{
    margin: 0;
    padding: 0;
    border:none;
}

img{
    vertical-align: top;
}

html,body{
    width: 100%;
    height: 100%;
}

#main{
    position: relative;
}

.box{
    float: left;
    padding: 15px 0 0 15px;
    /*background-color: red;*/
}

.pic{
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    background-color: #fff;
}

.pic img{
    width: 165px;
}
</style>
</head>

<body>
  <div id="main">
    <div class="box">
      <div class="pic"><img src="images/img01.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="pic"><img src="images/img02.jpg" alt=""></div>
    </div>
  </div>
  <script src="js/Underscore-min.js"></script>
  <script src="js/myFunc.js"></script>
  <script src="js/index.js"></script>
</body>

</html>
           
window.onload = function () {
    // 1. 實作瀑布流布局
    waterFull("main", "box");

    // 2. 動态加載圖檔
    var timer1 = null;
    window.onscroll = function () {
        clearTimeout(timer1);
        timer1 = setTimeout(function () {
            if(checkWillLoadImage()){
                // 2.1 造資料
                var dataArr = [
                    {"src": "img04.jpg"},
                    {"src": "img06.jpg"},
                    {"src": "img08.jpg"},
                    {"src": "img09.jpg"},
                    {"src": "img10.jpg"},
                    {"src": "img12.jpg"},
                    {"src": "img14.jpg"},
                    {"src": "img16.jpg"},
                    {"src": "img18.jpg"}
                ];

                // 2.2 建立元素
                for(var i=0; i<dataArr.length; i++){
                    var newBox = document.createElement("div");
                    newBox.className = "box";
                    $("main").appendChild(newBox);

                    var newPic = document.createElement("div");
                    newPic.className = "pic";
                    newBox.appendChild(newPic);

                    var newImg = document.createElement("img");
                    newImg.src = "images/" + dataArr[i].src;
                    newPic.appendChild(newImg);
                }

                // 2.3 重新布局
                waterFull("main", "box");
            }
        }, 200);
    };

    // 3. 視窗的大小發生改變
    var timer = null;
    window.onresize = function () {
        clearTimeout(timer);
        // 節流
        timer = setTimeout(function () {
            console.log(1);
            waterFull('main', 'box');
        }, 200);
    }
};

/**
 * 實作瀑布流布局
 */
function waterFull(parent, child) {
    // 1. 父盒子居中
    // 1.1 擷取所有的盒子
    var allBox = $(parent).getElementsByClassName(child);
    // 1.2 擷取子盒子的寬度
    var boxWidth = allBox[0].offsetWidth;
    // 1.3 擷取螢幕的寬度
    var screenW = document.documentElement.clientWidth;
    // 1.4 求出列數
    var cols = parseInt(screenW / boxWidth);
    // 1.5 父盒子居中
    $(parent).style.width = cols * boxWidth + 'px';
    $(parent).style.margin = "0 auto";


    // 2. 子盒子的定位
    // 2.1 定義高度數組
    var heightArr = [], boxHeight = 0, minBoxHeight = 0, minBoxIndex = 0;
    // 2.2 周遊子盒子
    for (var i = 0; i < allBox.length; i++) {
        // 2.2.1 求出每一個子盒子的高度
        boxHeight = allBox[i].offsetHeight;
        // 2.2.2 取出第一行盒子的高度放入高度數組
        if (i < cols) { // 第一行
            heightArr.push(boxHeight);
            allBox[i].style = '';
        } else { // 剩餘行
            // 1. 取出最矮的盒子高度
            minBoxHeight = _.min(heightArr);
            // 2. 求出最矮盒子對應的索引
            minBoxIndex = getMinBoxIndex(heightArr, minBoxHeight);
            // 3. 子盒子定位
            allBox[i].style.position = "absolute";
            allBox[i].style.left = minBoxIndex * boxWidth + 'px';
            allBox[i].style.top = minBoxHeight + 'px';
            // 4. 更新數組中的高度
            heightArr[minBoxIndex] += boxHeight;
        }
    }

    // console.log(heightArr, minBoxHeight, minBoxIndex);
}
/**
 * 擷取數組中最矮盒子高度的索引
 * @param arr
 * @param val
 * @returns {number}
 */
function getMinBoxIndex(arr, val) {
    for(var i=0; i<arr.length; i++){
        if(arr[i] === val){
            return i;
        }
    }
}
function $(id) {
    return typeof id === "string" ? document.getElementById(id) : null;
}
/**
 * 判斷是否具備加載圖檔的條件
 */
function checkWillLoadImage() {
    // 1. 擷取最後一個盒子
    var allBox = document.getElementsByClassName("box");
    var lastBox = allBox[allBox.length - 1];

    // 2. 求出最後一個盒子自身高度的一半 + offsetTop
    var lastBoxDis = lastBox.offsetHeight * 0.5 + lastBox.offsetTop;

    // 3. 求出螢幕的高度
    var screenW = document.body.clientHeight || document.documentElement.clientHeight;

    // 4. 求出頁面偏離浏覽器的高度
    var scrollTop = scroll().top;

    return lastBoxDis <= screenW + scrollTop;
}