JS实现瀑布流页面布局

个人对瀑布流布局理解:

每列的宽度相等而高度不等,且第二行的第一个容器需要放在第一行高度最小的容器下面,依次类推放置。

目前创新互联已为成百上千家的企业提供了网站建设、域名、网络空间、网站运营、企业网站设计、泰州网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。

附上代码:

代码仅实现了瀑布流的布局方式和 resize 监听,如果大家有需要,可以自己拓展下:实现监听滚动事件,页面滚动加载图片的功能。

代码中写了详细注释,可以直接使用。

DOCTYPE html>
<htmllang="en">
    <head>
        <metacharset="UTF-8" />
        <metahttp-equiv="X-UA-Compatible" content="IE=edge" />
        <metaname="viewport" content="width=device-width, initial-scale=1.0" />
        <title>瀑布流布局JS实现title>
    head>
    <body>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            body{
                width: 100vw;
                height: 100vh;
            }
            .container{
                width: 100vw;
                height: 100vh;
                overflow: scroll;
                position: relative;
                background-color: lightgray;
            }
            .item{
                width: 200px;
                height: auto;
                box-sizing: border-box;
                background: #fff;
                border: 1px solid #000;
                border-radius: 15px;
                text-align: center;
                font-size: 40px;
                font-weight: bold;
                position: absolute;
                top: 0;
                left: 0;
            }
            .item1,
            .item8{
                height: 300px;
            }
            .item2,
            .item6{
                height: 150px;
            }
            .item3,
            .item9{
                height: 120px;
            }
            .item4,
            .item10{
                height: 270px;
            }
            .item5,
            .item7{
                height: 350px;
            }
        style>
        <divclass="container">
            <divclass="item item1">1div>
            <divclass="item item2">2div>
            <divclass="item item3">3div>
            <divclass="item item4">4div>
            <divclass="item item5">5div>
            <divclass="item item6">6div>
            <divclass="item item7">7div>
            <divclass="item item8">8div>
            <divclass="item item9">9div>
            <divclass="item item10">10div>
        div>
        <script>
            function waterFullLayout() {
                console.log("start");
// 获取页面宽度
                let pageWidth=
                    document.getElementsByClassName("container")[0].clientWidth;
// 获取图片固定的宽度
                let itemWidth= document.getElementsByClassName("item")[0].offsetWidth;
// 设置图片之间间距
                let gap= 10;
// 获取一行最多可以展示几张图片
                let nums= Math.floor(pageWidth/ (itemWidth+ gap));
// 瀑布流实现原则:
                // 所有图片元素绝对定位,从第二行开始,依次从第一行图片元素高度最小的下方填充,这里注意,不是从左至右填充,即优先填补空位,填补一个后,再填补下一个较大的空位
                // 定义第一行图片的所有高度的数组,之后每张图片下方填充图片后,会更新数组对应位置下的最小高度
                let heightList= [];
                let itemArr= document.getElementsByClassName("item");
                let imgLen= itemArr.length;
for (let i= 0; i< imgLen; i++) {
// 如果 当前图片元素索引小于一行最多可以展示的图片个数,说明是第一行,top 已在css中默认设置为0,需要统一设置 left 值,top值如果加gap,则还需设置gap值
                    if (i< nums) {
// 将第一行的图片元素的高度放入 heightList 数组
                        heightList.push(itemArr[i].offsetHeight+ gap);
                        itemArr[i].style.top= gap+ "px";
                        itemArr[i].style.left= (itemWidth+ gap)* i+ "px";
                    }else {
// 否则从第二行开始,要根据第一行图片元素的高度,设置top和left
                        // 先假设 heightList[0] 为最小高度
                        let minItem= {
                            minHeight: heightList[0],
                            minIndex:0,
                        };
for (let j= 0; j< heightList.length; j++) {
if (heightList[j]< minItem["minHeight"]) {
                                minItem["minHeight"]= heightList[j];
                                minItem["minIndex"]= j;
                            }
                        }
                        itemArr[i].style.top= minItem["minHeight"]+ gap+ "px";
                        itemArr[i].style.left=
                            (itemWidth+ gap)* minItem["minIndex"]+ "px";
// 关键步骤,更新 heightList 中对应位置下整列图片的高度,以便在下次循环时根据heightList 重新寻找最小高度
                        heightList[minItem["minIndex"]]=
                            parseFloat(itemArr[i].style.top)+
                            parseFloat(itemArr[i].offsetHeight);
                    }
                }
            }
// 防抖
            function debounce(fn, delay) {
                let timer= null;
return function () {
if (timer) {
                        clearTimeout(timer);
                    }
                    timer= setTimeout(()=> {
                        fn.apply(this, arguments);
                    }, delay);
                };
            }
            window.onload= function () {
// 为了保证页面宽度可以正常获取,onload 之后再执行
                waterFullLayout();
            };
// 页面宽度变化要重新布局
            window.onresize= debounce(waterFullLayout,100);
script>
    body>
html>

网站栏目:JS实现瀑布流页面布局
URL分享:http://myzitong.com/article/dsojpco.html