瀑布流布局

瀑布流:每個內(nèi)容的寬度相等,高度是隨機的
布局的基本原則,第一排排滿之后,下面的元素將放到高度最短的那一列下面。

實現(xiàn)的基本思路:

  • 需要創(chuàng)建一個數(shù)組,這個數(shù)組存儲的每一項都為對應(yīng)列的高度,而下標(biāo)就為當(dāng)前的列
  • 需要得到每個元素的寬度

實現(xiàn)舉例:

<style>
        .content {
            position: relative;
        }
        .item {
            /*絕對定位,并且每個元素的寬度是一定的*/
            position: absolute;
            width: 200px;
            margin-right: 10px;
            margin-top:  10px;
            transition: all 1s;
        }
        .h1 {
            height: 200px;
            background: #f4b300;
        }
        .h2 {
            height: 300px;
            background: #691bbb;
        }
        .h3 {
            height: 400px;
            background: #006ac1;
        }
    </style>
</head>
<body>
     <div class="content">
         <div class="item h1">1</div>
         <div class="item h3">2</div>
         <div class="item h2">3</div>
         <div class="item h2">4</div>
         <div class="item h3">5</div>
         <div class="item h1">6</div>
         <div class="item h2">7</div>
         <div class="item h3">8</div>
         <div class="item h1">9</div>
         <div class="item h2">10</div>
         <div class="item h3">11</div>
         <div class="item h3">12</div>
         <div class="item h2">13</div>
         <div class="item h1">14</div>
     </div>

結(jié)構(gòu)和樣式如上,h1,h2,h3用來模擬隨機的高度。
JS部分如下:

     <script src="../jquery-3.2.1.min.js"></script>
     <script>
//         創(chuàng)建數(shù)組
         var itemArr = [];
         //得到數(shù)組一共有多少項,即要排列的元素到底有幾列,可以通過content的寬度除以item的寬度,然后進(jìn)行取整就能得到總共有多少列
         var itemColumn = parseInt($('.content').width() / $('.item').width());
//         console.log(itemColumn)
         //進(jìn)行數(shù)組的初始化,有itemColumn項,每項都先設(shè)為0,表示當(dāng)前沒有元素,高度為0
         for (var i = 0; i < itemColumn; i ++) {
            itemArr[i] = 0;
         }
         //數(shù)組初始化完畢,然后涉及到需要得到數(shù)組中值最小的一項,以及要得到最小的這一項的下標(biāo),可以使用Math.min和indexOf()兩個方法
         //進(jìn)行遍歷所有的item,將每個item放到當(dāng)前高度最短的那一列的下邊
         $('.item').each(function () {
             var minHeight = Math.min.apply(null,itemArr);//數(shù)組中值最小的一項,即高度最短的那一列的高度值
             var minIndex = itemArr.indexOf(minHeight); // 對應(yīng)列的下標(biāo)
             $(this).css({
                 left: minIndex * $('.item').outerWidth(true), //這個outerWidth,有true代表包括margin,不寫true代表只包括border
                 top: minHeight,
             })
             itemArr[minIndex] += $(this).outerHeight(true); //放置完當(dāng)前遍歷元素時,將相應(yīng)的高度加到當(dāng)前列的高度上
//             console.log('h',minHeight)
//             console.log('i',minIndex);
         })
     </script>

代碼的整體思路已經(jīng)很清晰了,但是有地方需要注意:

  • 涉及到需要得到數(shù)組中值最小的一項,以及要得到最小的這一項的下標(biāo),可以使用Math.min和indexOf()兩個方法。使用Math.min要結(jié)合apply()
  • $('.item').outerWidth(true)

然后基本效果就達(dá)到了,但是需要監(jiān)聽窗口大小改變的事件,如果窗口大小改變,重新排列一下。所以我們封裝一下我們得到的代碼。加上監(jiān)聽事件

         waterFall(); //頁面初始化時先執(zhí)行一次出現(xiàn)布局
         $(window).on('resize',function () { // 監(jiān)聽瀏覽器窗口大小改變的事件
             waterFall();
         })
        
         
        function waterFall() {
            //         創(chuàng)建數(shù)組
            var itemArr = [];
            //得到數(shù)組一共有多少項,即要排列的元素到底有幾列,可以通過content的寬度除以item的寬度,然后進(jìn)行取整就能得到總共有多少列
            var itemColumn = parseInt($('.content').width() / $('.item').width());
//         console.log(itemColumn)
            //進(jìn)行數(shù)組的初始化,有itemColumn項,每項都先設(shè)為0,表示當(dāng)前沒有元素,高度為0
            for (var i = 0; i < itemColumn; i ++) {
                itemArr[i] = 0;
            }
            //數(shù)組初始化完畢,然后涉及到需要得到數(shù)組中值最小的一項,以及要得到最小的這一項的下標(biāo),可以使用Math.min和indexOf()兩個方法
            //進(jìn)行遍歷所有的item,將每個item放到當(dāng)前高度最短的那一列的下邊
            $('.item').each(function () {
                var minHeight = Math.min.apply(null,itemArr);//數(shù)組中值最小的一項,即高度最短的那一列的高度值
                var minIndex = itemArr.indexOf(minHeight); // 對應(yīng)列的下標(biāo)
                $(this).css({
                    left: minIndex * $('.item').outerWidth(true), //這個outerWidth,有true代表包括margin,不寫true代表只包括border
                    top: minHeight,
                })
                itemArr[minIndex] += $(this).outerHeight(true); //放置完當(dāng)前遍歷元素時,將相應(yīng)的高度加到當(dāng)前列的高度上
//             console.log('h',minHeight)
//             console.log('i',minIndex);
            })
        }

此時窗口大小改變時也會相應(yīng)的重新布局了。還可以進(jìn)一步封裝代碼,創(chuàng)建一個對象,把要執(zhí)行的代碼return出來,函數(shù)體放到對象內(nèi)部的屬性中。

         var begin = {
             run: run,
         };
         begin.run();
         function run () {
             function waterFall() {
                 //         創(chuàng)建數(shù)組
                 var itemArr = [];
                 //得到數(shù)組一共有多少項,即要排列的元素到底有幾列,可以通過content的寬度除以item的寬度,然后進(jìn)行取整就能得到總共有多少列
                 var itemColumn = parseInt($('.content').width() / $('.item').width());
//         console.log(itemColumn)
                 //進(jìn)行數(shù)組的初始化,有itemColumn項,每項都先設(shè)為0,表示當(dāng)前沒有元素,高度為0
                 for (var i = 0; i < itemColumn; i ++) {
                     itemArr[i] = 0;
                 }
                 //數(shù)組初始化完畢,然后涉及到需要得到數(shù)組中值最小的一項,以及要得到最小的這一項的下標(biāo),可以使用Math.min和indexOf()兩個方法
                 //進(jìn)行遍歷所有的item,將每個item放到當(dāng)前高度最短的那一列的下邊
                 $('.item').each(function () {
                     var minHeight = Math.min.apply(null,itemArr);//數(shù)組中值最小的一項,即高度最短的那一列的高度值
                     var minIndex = itemArr.indexOf(minHeight); // 對應(yīng)列的下標(biāo)
                     $(this).css({
                         left: minIndex * $('.item').outerWidth(true), //這個outerWidth,有true代表包括margin,不寫true代表只包括border
                         top: minHeight,
                     })
                     itemArr[minIndex] += $(this).outerHeight(true); //放置完當(dāng)前遍歷元素時,將相應(yīng)的高度加到當(dāng)前列的高度上
//             console.log('h',minHeight)
//             console.log('i',minIndex);
                 })
             }
            return (function () {
                waterFall(); //頁面初始化時先執(zhí)行一次出現(xiàn)布局
                $(window).on('resize',function () { // 監(jiān)聽瀏覽器窗口大小改變的事件
                    waterFall();
                })
            })();
         }

封裝代碼如上所示,把函數(shù)體放到run()中,作為值傳遞給begin對象的run屬性,return的是包含我們想要執(zhí)行的代碼的立即執(zhí)行函數(shù),這樣我們想要開始的時候,只需要調(diào)用begin對象的run屬性即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容