多欄布局與JS實現瀑布流


css3屬性之多欄布局與JS實現瀑布流

   背景:之前打算自己總結一下flex布局的知識點,發現自己無從下手,原因在何處:我反思了一下,其實原因很簡單,使用的次數少,更多的時間使用了百分比,浮動和定位解決。這也就顯示出了博客和筆記的區別,自己平時做筆記,更多的記錄,而不是總結,其實自己沒有熟練掌握。

  有的時候甚至出現了這樣的筆記:

 我打算堅持寫博客,不論自己總結有多么差勁,也要堅持寫,哪怕幾年后我看到以前的筆記,自己會偷偷笑出聲。想想原來大一時的技術還是那樣的稚嫩啊。

Css3多列

  1)首提的兼容性問題:IE10以及opera支持多列(column),chrome需要-webkit-前綴,Firefox需要-moz-的前綴,Ie9以及更早版本就不支持多列了。你可以使用這個工具,很方便的查看你的瀏覽器內核以及版本信息http://ie.icoa.cn/

  2)Css3多列屬性:css3多列主要是五個屬性

column-count   <規定元素被分隔的列數>

column-gap    <規定列與列之間的間隔>

column-rule      <列之間的寬度、樣式、顏色>

column-width        <列的寬度>

column-span         <元素應該橫跨的列數>

 注意:在設置column-width寬度時,同時設置盒子的width,否則寬度默認為100%,每欄寬度按欄數平均分;盒子每欄寬度必須大於等於column-width設定的值,否則就會減少欄數來增加每欄寬度

css3多列和JS實現瀑布流

 給自己安利一波吧,看到網上很多瀑布流的效果,哇,簡直棒極了有沒有;於是我迫不及待的打開vpn,打開了pinterest的官網。

自己也梳理梳理邏輯:<在寫js代碼之前,一定要先搞清邏輯,再動手寫代碼>

我們都不陌生瀑布流是同寬的,但是高度不一,js主要的工作就是根據高度來進行布局,

1)當一行排滿后,准備排第二行的時候,把第一個圖片放到上一行圖片高度最小處,以此類推,

另外有一點就是自動加載,這里我做一個條件來判斷是否加載,

2)當最后一個的元素距離網頁頂部的高度(offsetTop)+ 這個元素高度的一半 < 垂直方向上滾輪的量(scrollTop) + 網頁可見區域的高 時:

我們就加載圖片(這里我沒有用ajax請求,我用了一個json數組來模擬json數據)

要搞清楚offsetTop、scrollTop、clientHeight這些的具體含義:可以參考前輩的博客

 


 

梳理完邏輯,讓我們動手寫代碼吧:

  html比較簡單,這里圖片我用了placehold的圖片占位符,如果你沒有很好的素材,這也許是個不錯的選擇

<body>
<div class="main clearfix" id="main">
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x150"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x100"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x150"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x200"/></div>
    </div>
    <div class="box">
        <div class="pic"><img src="http://placehold.it/200x300"/></div>
    </div>
</div>

  css用了多列的column-width和column-gap屬性

* {
            margin: 0;
            padding: 0;
        }

        .clearfix:after,
        .clearfix:before {
            content: "";
            display: table;
        }

        .clearfix:after {
            clear: both;
        }

        .main {
            position: relative;
            -webkit-column-width: 210px;
            -webkit-column-gap: 5px;
            -moz-column-gap: 5px;
        }

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

        .box .pic {
            width: 200px;
            height: auto;
            padding: 10px;
            border-radius: 10px;
            box-shadow: 0px 0 5px #ccc;
        }

        .box .pic img {
            display: block;
            width: 100%;
        }

  梳理完了邏輯,該動手寫js

 window.onload = function () {

            waterfall('main', 'box');

            var ImgJson = {
                'data': [
                    {'src': 'http://placehold.it/200x300'}

                ]
            };

            //監聽scroll事件
            window.onscroll = function () {
                var isPosting = false;
                if (checkScrollSlide('main', 'box') && !isPosting) {
                    var oParent = document.getElementById('main');
                    for (var i in ImgJson.data) {
                        var oBox = document.createElement('div');
                        oBox.className = 'box';
                        oBox.innerHTML = '<div class="pic"><img src="' + ImgJson.data[i].src + '"></div>';
                        oParent.appendChild(oBox);
                    }
                    isPosting = false;
                    waterfall('main', 'box');
                }
            }
        };

        function waterfall(parent, clsName) {
            //獲取元素
            var oParent = document.getElementById(parent);
            //獲取所有box
            var aBoxArr = oParent.getElementsByClassName(clsName);
            //單個box的寬度
            var iBoxw = aBoxArr[0].offsetWidth;
            //列數
            var cols = Math.floor(document.documentElement.clientWidth / iBoxw);
            oParent.style.cssText = 'width:' + iBoxw * (cols + 1) + 'px;margin:0 auto;';

            //儲存所有高度
            var hArr = [];
            for (var i = 0; i < aBoxArr.length; i++) {
                if (i < cols) {
                    hArr[i] = aBoxArr[i].offsetHeight;
                } else {
                    //獲取hArr的最小值
                    var minH = Math.min.apply(null, hArr);
                    //hArr最小值索引index
                    var minHIndex = getMinHIndex(hArr, minH);
                    aBoxArr[i].style.cssText = 'position:absolute;top:' + minH + 'px;left:' + aBoxArr[minHIndex].offsetLeft + 'px';

                    //添加元素之后更新hArr
                    hArr[minHIndex] += aBoxArr[i].offsetHeight;
                }
            }
        }

        //獲取最小索引值
        function getMinHIndex(arr, val) {
            for (var i in arr) {
                if (arr[i] == val) {
                    return i;
                }
            }
        }

        //檢查是否滿足加載數據的條件
        function checkScrollSlide(parent, clsName) {
            var oParent = document.getElementById(parent);
            var aBoxArr = oParent.getElementsByClassName(clsName);
            //最后一個box元素的offsetTop+高度的一半
            var lastBoxH = aBoxArr[aBoxArr.length - 1].offsetTop + aBoxArr[aBoxArr.length - 1].offsetHeight / 2;

            var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
            var height = document.documentElement.clientHeight || document.body.clientHeight;
            return lastBoxH < scrollTop + height;
        }

 

  最后走一波效果圖

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM