前言:
这玩意儿大家肯定经常见到,但是应该怎么实现的呢?现在列出来三种方式
源码:(还未上传,稍等)
第一种:通过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="600px"> 主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列 主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列 主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列 <h2>主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列</h2> <div> 主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列 主要用于文字分列,主要用于文字分列,主要用于文字分列,主要用于文字分列 </div> </div> <div class="box" style="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); }