網頁的瀑布流佈局

FreeeLinux發表於2017-11-10

程式碼

本文實現網頁的瀑布流佈局,用三種方法,分別是javascript,jQuery和CSS3。
首先是HTML:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>瀑布流</title>
    <!--方式一和二所用css-->
    <!--<link rel="stylesheet" href="css/style.css">-->
    <!--方式三:CSS3-->
    <link rel="stylesheet" href="css/css3.css">

</head>
<body>
<div id="main">
    <div class="box">
        <div class="pic">
            <img src="images/0.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/1.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/2.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/3.jpg" alt="">
        </div>
        `
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/4.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/5.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/6.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/7.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/8.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/9.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/10.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/11.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/12.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/13.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/14.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/15.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/16.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/17.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/18.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/19.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/20.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/21.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/22.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/0.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/1.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/2.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/3.jpg" alt="">
        </div>
        `
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/4.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/5.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/6.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/7.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/8.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/9.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/10.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/11.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/12.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/13.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/14.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/15.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/16.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/17.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/18.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/19.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/20.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/21.jpg" alt="">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/22.jpg" alt="">
        </div>
    </div>

</div>
</body>
<!--方式二:jQuery-->
<!--<script type="text/javascript" src="js/jquery.min.js"></script>-->
<!--<script type="text/javascript" src="js/jqueryScript.js"></script>-->

<!--方式一:原生js-->
<!--<script type="text/javascript" src="js/javaScript.js"></script>-->
</html>

1.原生js實現

window.onload = function () {
    waterfall('main', 'box');

    var dataInt = {data:[{src:'0.jpg'},{src:'1.jpg'},{src:'3.jpg'}]};
    window.onscroll = function () {
        if (checkScrollSlide()) {
            var oParent = document.getElementById('main');
            for(var i = 0; i < dataInt.data.length; ++i) {
                var oBox = document.createElement('div');
                oBox.className = 'box';
                oParent.appendChild(oBox);
                var oPic = document.createElement('div');
                oPic.className = 'pic';
                oBox.appendChild(oPic);
                var oImg = document.createElement('img');
                oImg.src = 'images/' + dataInt.data[i].src;
                oPic.appendChild(oImg);
            }
            waterfall('main', 'box');
        }
    }
};

function waterfall(parent, box) {
    //將main下的所有class為box的元素取出來
    var oParent = document.getElementById(parent);
    var oBoxs = getByClass(oParent, box);
    //計算整個頁面顯示地列數(頁面的寬度/box的寬度),瀑布流等寬不等高,隨便獲取一個寬度即可
    var oBoxW = oBoxs[0].offsetWidth;
    //document.documentElement即文件的root節點,html節點
    var cols = Math.floor(document.documentElement.clientWidth / oBoxW);
    oParent.style.cssText = 'width:' + oBoxW * cols + 'px;margin: 0 auto;';
    var hArr = [];   //存放每一列高度陣列
    for (var i = 0; i < oBoxs.length; ++i) {
        if (i < cols) {
            hArr.push(oBoxs[i].offsetHeight);
        } else {
            var minH = Math.min.apply(null, hArr);
            var index = getMinHIndex(hArr, minH);
            oBoxs[i].style.position = 'absolute';
            oBoxs[i].style.top = minH + 'px';
            oBoxs[i].style.left = oBoxW * index + 'px';
            hArr[index] += oBoxs[i].offsetHeight;
        }
    }
}

//根據class獲取元素
function getByClass(parent, className) {
    var boxArr = [];   //用來儲存獲取到的所有class為box的元素
    oElements = parent.getElementsByTagName('*');
    for (var i = 0; i < oElements.length; ++i) {
        if (oElements[i].className === className) {
            boxArr.push(oElements[i]);
        }
    }
    return boxArr;
}

function getMinHIndex(arr, val) {
    for (var i in arr) {
        if (arr[i] === val) {
            return i;
        }
    }
    return -1;
}

function checkScrollSlide() {
    var oParent = document.getElementById('main');
    var oBoxs = getByClass(oParent, 'box');
    var lastBoxH = oBoxs[oBoxs.length-1].offsetTop + Math.floor(oBoxs[oBoxs.length-1].offsetHeight / 2);
    //混雜模式與標準模式
    //滑動距離
    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    //視窗高度
    var height = document.body.clientHeight || document.documentElement.clientHeight;
    return lastBoxH < scrollTop + height;
}

2.jQuery實現

$(window).on('load', function () {
    waterfall();

    var dataInt = {data: [{src: '0.jpg'}, {src: '1.jpg'}, {src: '3.jpg'}]};
    $(window).on('scroll', function () {
        if (checkScrollSlide()) {
            $.each(dataInt.data, function (index, value) {
                //$('<div>')即建立一個div
                var oBox = $('<div>').addClass('box').appendTo($('#main'));
                var oPic = $('<div>').addClass('pic').appendTo(oBox);
                console.log(value.src);
                $('<img>').attr('src', 'images/' + value.src).appendTo(oPic);
            });
            waterfall();
        }
    })
});

function waterfall() {
    var boxs = $('#main>div');
    //width只獲取定義寬度,outerWidth包括padding,
    var w = boxs.eq(0).outerWidth();
    var cols = Math.floor($(window).width() / w);

    $('#main').width(w * cols).css('margin', '0 auto');

    var hArr = [];
    boxs.each(function (index, value) {
        var h = boxs.eq(index).outerHeight();
        if (index < cols) {
            hArr[index] = h;
        } else {
            var minH = Math.min.apply(null, hArr);
            var minHIndex = $.inArray(minH, hArr);
            //將DOM物件轉化為jQuery物件,直接$()即可!!!
            //此處value是一個DOM物件
            $(value).css({
                'position': 'absolute',
                'top': minH + 'px',
                'left': minHIndex * w + 'px'
            });
        }
        hArr[minHIndex] += boxs.eq(index).outerHeight();
    })

}

function checkScrollSlide() {
    var lastBox = $('#main>div').last();
    var lastBoxDis = lastBox.offset().top + Math.floor(lastBox.outerHeight() / 2);
    var scrollTop = $(window).scrollTop();
    var documentH = $(window).height();
    return lastBoxDis < scrollTop + documentH;
}

以上兩種方法配套的CSS的

* {
    margin: 0;
    padding: 0;
}

#main {
    position: relative;
}

.box {
    padding: 15px 0 0 15px;
    float: left;
}

.pic {
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    box-shadow: 0 0 5px #ccc;
}

.pic img {
    width: 165px;
    height: auto;
}
  1. CSS3實現方式
#main {
    /*寬度*/
    -webkit-column-width: 202px;
    -moz-column-width: 202px;
    -o-column-width: 202px;
    -ms-column-width: 202px;
    /*列數目*/
    /*-webkit-column-count: 5;*/
    /*-moz-column-count: 5;*/
    /*-o-column-count: 5;*/
    /*-ms-column-count: 5;*/
    /*邊框*/
    /*-webkit-column-rule: 2px dashed #f00;*/
    /*-moz-column-rule: 2px dashed #f00;*/
    /*-o-column-rule: 2px dashed #f00;*/
    /*-ms-column-rule: 2px dashed #f00;*/
    /*間隙,大約為5,因為不能整除的部分會平均*/
    -webkit-column-gap: 5px;
    -moz-column-gap: 5px;
    -o-column-gap: 5px;
    -ms-column-gap: 5px;
}

.box {
    padding: 10px 0 0 15px;
}

.pic {
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    box-shadow: 0 0 5px #ccc;
    width: 165px;
}

.pic img {
    display: block;
    width: 165px;
    height: auto;
}

優缺點

javascript方式

  1. 需要計算列數=瀏覽器視窗/圖片寬度,圖片定位是根據每一列資料庫的高度計算接下來圖片的位置。

CSS3方式

  1. 不需要計算,瀏覽器自動計算,只需設定列寬,效能高
  2. 列寬隨著瀏覽器視窗大小進行改變,使用者體驗不好

相關文章