原生js瀑布流

前言:

  这玩意儿大家肯定经常见到,但是应该怎么实现的呢?现在列出来三种方式

  源码:(还未上传,稍等)

 

 

第一种:通过html标签实现,比如分3列,将数据平分为3份分别填充。

  适合:图片高度一致。

  优点:简单

  缺点:因为每个数据不一样,每一列的高低可能相差比较大。

代码如下:

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>瀑布流1</title>
        <link rel="stylesheet" href="1.css">
        <script src="1.js"></script>
    </head>

    <body>
        <div id="box">
        </div>
    </body>
    <script>
        //存放参数
        let box = document.getElementById("box");       //元素
        let width = 600;        //宽度,单位px
        let jianJu = 6;         //每列之间的间距,单位px
        let col = 3;            //分为多少列
        let dataList = [
            {
                url: "http://pic.sc.chinaz.com/Files/pic/pic9/202007/apic26715_s.jpg",
                title: "1行主题",
                content: "1行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26552_s.jpg",
                title: "1行主体",
                content: "2行内容2行内容2行内容2行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26408_s.jpg",
                title: "1行主题",
                content: "3行内容"
            },
            {
                url: "http://pic.sc.chinaz.com/Files/pic/pic9/202007/apic26313_s.jpg",
                title: "1行主题",
                content: "4行内容"
            },
            {
                url: "http://pic1.sc.chinaz.com/Files/pic/pic9/202007/bpic20697_s.jpg",
                title: "1行主题",
                content: "5行内容"
            },
            {
                url: "http://pic1.sc.chinaz.com/Files/pic/pic9/202004/bpic20013_s.jpg",
                title: "2行主题",
                content: "1行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202005/apic25546_s.jpg",
                title: "3行主题",
                content: "1行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202005/apic25309_s.jpg",
                title: "4行主题",
                content: "1行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26488_s.jpg",
                title: "4行主题",
                content: "4行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26473_s.jpg",
                title: "超过2行的主题",
                content: "超过3行的内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26395_s.jpg",
                title: "其他",
                content: "其他"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202005/apic25357_s.jpg",
                title: "其他",
                content: "其他"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202005/apic25357_s.jpg",
                title: "其他",
                content: "其他"
            }
        ]
    </script>
    <script>
        //调用
        aaa(box, width, col, dataList);
    </script>

</html>
.div-class{
    float: left;
}
/*标题文字的样式*/
.tit{   
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;

    font-weight: bold;
}
/*介绍文字的样式*/
.con{
    
}
function aaa(ele, wid, num, arr) {
    let _this = this;
    let nData = Math.round(arr.length / num);   // 先将数据(arr)分为n(num)份
    let colWidth = wid / num;
    for (let i = 0; i < num; i++) {
        let colDiv = document.createElement('div');
        let startIndex = nData * i;         // 每份数据开始的索引
        let newData = null;
        colDiv.style.width = colWidth + "px";
        colDiv.style.marginLeft = jianJu + "px";
        colDiv.className = "div-class";
        
        if (i==num-1) {
            newData = arr.slice(startIndex, arr.length + 1);    //最后一部分数据
        } else {
            newData = arr.slice(startIndex, startIndex + nData);
        }
        for (let j = 0; j < newData.length; j++) {
            let childDiv = document.createElement("p");
            _this.pStyle(childDiv, newData[j], colWidth);
            colDiv.appendChild(childDiv);
        }
        ele.appendChild(colDiv);
    }
}

function pStyle(p, item, colWidth) {
    let img = document.createElement('img');
    let tit = document.createElement('p');
    let con = document.createElement('p');
    img.src = item.url;
    img.style.width = colWidth + 'px';
    tit.className = "tit";
    tit.innerHTML = item.title;
    con.className = "con";
    con.innerHTML = item.content;
    p.appendChild(img);
    p.appendChild(tit);
    p.appendChild(con);
}

 

第二种:通过css实现

  适合:文本分列

  优点:简单

  缺点:因为图片高低不一,页面不一致

代码如下:

 

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>瀑布流2</title>
        <link rel="stylesheet" href="2.css">
    </head>

    <body>

        <div class="box" style="width:600px">
            主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列
            主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列
            主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列
            <h2>主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列</h2>
            <div>
                主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列
                主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列
            </div>
        </div>

        <div class="box" style="width:600px">

        </div>

    </body>
    <script>
        //存放参数
        let box = document.getElementsByClassName("box")[1];       //元素
        let dataList = [
            {
                url: "http://pic.sc.chinaz.com/Files/pic/pic9/202007/apic26715_s.jpg",
                title: "1行主题",
                content: "1行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26552_s.jpg",
                title: "1行主体",
                content: "2行内容2行内容2行内容2行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26408_s.jpg",
                title: "1行主题",
                content: "3行内容"
            },
            {
                url: "http://pic.sc.chinaz.com/Files/pic/pic9/202007/apic26313_s.jpg",
                title: "1行主题",
                content: "4行内容"
            },
            {
                url: "http://pic1.sc.chinaz.com/Files/pic/pic9/202007/bpic20697_s.jpg",
                title: "1行主题",
                content: "5行内容"
            },
            {
                url: "http://pic1.sc.chinaz.com/Files/pic/pic9/202004/bpic20013_s.jpg",
                title: "2行主题",
                content: "1行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202005/apic25546_s.jpg",
                title: "3行主题",
                content: "1行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202005/apic25309_s.jpg",
                title: "4行主题",
                content: "1行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26488_s.jpg",
                title: "4行主题",
                content: "4行内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26473_s.jpg",
                title: "超过2行的主题",
                content: "超过3行的内容"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26395_s.jpg",
                title: "其他",
                content: "其他"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202005/apic25357_s.jpg",
                title: "其他",
                content: "其他"
            },
            {
                url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202005/apic25357_s.jpg",
                title: "其他",
                content: "其他"
            }
        ]
    </script>
    <script>
        for (let a = 0; a < dataList.length; a++) {
            var img = document.createElement("img");
            img.src = dataList[a].url;

            box.appendChild(img);
        }
    </script>

</html>
*{
    margin: 0;
    padding: 0;
}
.box{
    -webkit-column-count: 3; /* Chrome, Safari, Opera */
    -moz-column-count: 3; /* Firefox */
    column-count: 3;    /*创建多列*/

    -webkit-column-gap: 10px; /* Chrome, Safari, Opera */
    -moz-column-gap: 10px; /* Firefox */
    column-gap: 10px;      /*列与列间的间隙*/

    -webkit-column-rule-style: solid; /* Chrome, Safari, Opera */
    -moz-column-rule-style: solid; /* Firefox */
    column-rule-style: solid;   /*列与列间的边框样式*/
    -webkit-column-rule-width: 1px; /* Chrome, Safari, Opera */
    -moz-column-rule-width: 1px; /* Firefox */
    column-rule-width: 1px;
    -webkit-column-rule-color: lightblue; /* Chrome, Safari, Opera */
    -moz-column-rule-color: lightblue; /* Firefox */
    column-rule-color: lightblue;

    -webkit-column-width: 100px; /* Chrome, Safari, Opera */
    column-width: 100px;    /*指定列的宽度*/
}
h2{
    -webkit-column-span: all; /* Chrome, Safari, Opera */
    column-span: all;       /*指定元素跨越多少列*/
}
img{
    width: 100%;
}

 

第三种:通过js实现,检测每一列的高度,然后选择最低的插入数据

  适合:兼容

  优点:不会出现每列高度差很多的情况

  缺点:能耗高,数据多的话效率慢

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>瀑布流3</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .tit {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;

            font-weight: bold;
        }

        .con {

        }
    </style>
    <script src="3.js"></script>
</head>

<body>
    <div id="waterFallBox">

    </div>
</body>

<script>
    // 分为N列
    // 每列的高度为 heightList = [100, 200, 300, 400, 200, 400.....]
    //  每次插入前,选出最低的一列
    //  然后插入
    //  最后更新数组信息,重复以上步骤

    let boxWidth = 600;     //外层div的宽度
    let N = 3;              //分为N列
    let mar = 5;           //列与列之间的宽度
    let round = {
        is: true,            //是否圆角
        content: "5px"       //设置圆角(is为true时生效)
    };
    let dataList = [        //需要填充的数据
        {
            url: "http://pic.sc.chinaz.com/Files/pic/pic9/202007/apic26715_s.jpg",
            title: "1行主题",
            content: "1行内容"
        },
        {
            url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26552_s.jpg",
            title: "1行主体",
            content: "2行内容2行内容2行内容2行内容"
        },
        {
            url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26408_s.jpg",
            title: "1行主题",
            content: "3行内容"
        },
        {
            url: "http://pic.sc.chinaz.com/Files/pic/pic9/202007/apic26313_s.jpg",
            title: "1行主题",
            content: "4行内容"
        },
        {
            url: "http://pic1.sc.chinaz.com/Files/pic/pic9/202007/bpic20697_s.jpg",
            title: "1行主题",
            content: "5行内容"
        },
        {
            url: "http://pic1.sc.chinaz.com/Files/pic/pic9/202004/bpic20013_s.jpg",
            title: "2行主题",
            content: "1行内容"
        },
        {
            url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202005/apic25546_s.jpg",
            title: "3行主题",
            content: "1行内容"
        },
        {
            url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202005/apic25309_s.jpg",
            title: "4行主题",
            content: "1行内容"
        },
        {
            url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26488_s.jpg",
            title: "4行主题",
            content: "4行内容"
        },
        {
            url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26473_s.jpg",
            title: "超过2行的主题",
            content: "超过3行的内容"
        },
        {
            url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202007/apic26395_s.jpg",
            title: "其他",
            content: "其他"
        },
        {
            url: "http://pic2.sc.chinaz.com/Files/pic/pic9/202005/apic25357_s.jpg",
            title: "其他",
            content: "其他"
        },
        {
            url: "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2760607627,944470302&fm=26&gp=0.jpg",
            title: "其他",
            content: "其他"
        }
    ]

    window.onload = function () {
        this.appendChild();
    }        
</script>

</html>

 

function appendChild() {
    let box = document.getElementById("waterFallBox");      
    for (let i = 0; i < N; i++) {                   //根据需要生成N列,然后装饰一下
        let childBox = document.createElement("div");       
        childBox.className = 'water-fall' + i;
        childBox.style.width = boxWidth/N + 'px';
        childBox.style.float = "left"; 
        childBox.style.marginLeft = mar + 'px';
        childBox.style.marginRight = mar + 'px';

        box.appendChild(childBox);
    }
    for (let j = 0; j < dataList.length; j++) {         //每次填充一个数据就检测一次每一列的高度,找出最低的填充
        this.imgNodes(dataList[j]);
    }
}
function imgNodes(imgData) {
    let heightList = [];
    let minHeight = Infinity;
    let minIndex = 0;
    let createImgNode = null;
    let chooseNode = null;
    let nodeList = [];
    for (let i = 0; i < N; i++) {
        let node = document.getElementsByClassName('water-fall' + i)[0];
        nodeList.push(node);
        heightList.push(node.clientHeight);
    }

    for (let j = 0; j < heightList.length; j++) {       //找出最低列
        if (minHeight > heightList[j]) {
            minHeight = heightList[j];
            minIndex = j;
        }
    }
    //填充数据
    createImgNode = document.createElement('img');
    createTitNode = document.createElement('p');
    createContNode = document.createElement('p');
    createImgNode.src = imgData.url;
    createImgNode.style.width = boxWidth/N + 'px';
    if(round.is){
        createImgNode.style.borderRadius = round.content;
    }
    createTitNode.innerHTML = imgData.title;
    createTitNode.className = "tit";
    createContNode.innerHTML = imgData.content;
    createContNode.className = "con";
    
    nodeList[minIndex].appendChild(createImgNode);
    nodeList[minIndex].appendChild(createTitNode);
    nodeList[minIndex].appendChild(createContNode);
}
posted @ 2020-08-01 21:23  不叫一日闲过  阅读(143)  评论(0编辑  收藏  举报