首页 > 编程知识 正文

瀑布流布局的思路(瀑布流式页面布局的好处)

时间:2023-05-03 13:48:33 阅读:69130 作者:3614

本文序言原生JS实现瀑布流column多排布局,实现瀑布流flex属性,实现瀑布流列数动态瀑布流

前言

在写项目的过程中,整个页面分为三列,每列宽相等高度不同,而且第二行的第一个容器需要放在第一行高度最小的容器下,所以在网上查了一下。 这种布局方式称为瀑布布局

母语JS实现瀑布流,首先分析了母语JS实现瀑布流布局的原理:

瀑布布局的最大特点是,使用等宽不均的瀑布布局时,页面最后一行的容器高度差最小。 因此,从第二行开始,每个容器位于第一行容器的最小高度下,并且所有容器(子元素)都是一个大容器(父元素),类似于父元素设置绝对定位和http://www.com

divid=' wrap ' divclass=' item1'1/divdivclass=' item2'2/divdivclass=' item3'3/divdivclass=' item4'4/4

* { margin: 0; padding: 0; }body { padding: 10px; 背景色:灯光灰色; } body :3360-WebKit-scroll bar { width :4 px; height: 1px; } body :3360-WebKit-scroll bar-thumb { border-radius 33602 px; 背景: # e0e0e 0; } body :3360-WebKit-scroll bar-track { border-radius 336010 px; 后台: # FFf; }#wrap { width: 100%; 高海拔: calc (100 VH-20px; /*父元素设置相对位置*/position: relative; } # wrap div { width : calc (100 %/3-20px/3 ); 背景色: # fff; border-radius: 8px; /*子要素设定绝对位置*/position: absolute; /*初始左、上距离均设定为0 */left: 0; top: 0; font-size: 40px; 字体权重: bold; 文本对齐3360中心; }#wrap div img{ width: 100%; border-radius: 8px 8px 0 0; 垂直对齐: bottom } # wrapdivp { font-size 336024 px; }.item1 { height: 200px; }.item2 { height: 250px; }.item3 { height: 150px; }.item5, item7 { height: 200px; }.item4, item10 { height: 150px; }.item6 { height: 240px; }.item9 { height: 200px; }.item8 { height: 250px; }在这个项目中,我们发现整个页面分为三列,所以我们用css计算了宽度

接下来,主要分析js代码

//cdn中jqueryscriptsrc=' https://cdn.bootcdn.net/Ajax/libs/jquery/3.6.0/jquery.js '/使用需要部署scriptscriptletdivlive布局显示的div容器divlist=Array.from(divlist ) array的from )方法将伪数组转换为真正的数组let pagew=document

器的宽度 let cols = Math.floor(pageW / divW) // 计算一行能够放几个div容器 let arrH = [] // 用来存储每个div容器的高度 // 循环div容器的数组 divList.forEach((item, index) => { // 1. 对下标小于一行个数的div容器进行操作 if (index < cols) { arrH.push(item.clientHeight) // 将div容器的高度放入数组中 item.style.left = index * divW + index * 10 + 'px' // 同时设置每个容器的left值,第一行top都为0 } }) // 2. 对剩余的div容器进行循环 for (let i = cols; i < divList.length; i++) { let minH = Math.min.apply(Math, arrH), // 获取到数组中最小的高度 idx_min = arrH.indexOf(minH) // 查找到最小高度的下标 divList[i].style.left = divList[idx_min].style.left // 让当前的div容器和最小下标的left值相同 divList[i].style.top = minH + 10 + 'px' // top值在原来的最小高度上+10(为了是容器之间有一个间隙,可随意写) // 最小列的高度 = 当前自己的高度 + 新容器的高度 + 间隙 arrH[idx_min] = minH + divList[i].clientHeight + 10 }</script>

实现的结果图如下


可以放置图片查看效果

column多列布局实现瀑布流

首先分析下实现原理:

因为是用css的column布局实现的,所以就没有用到js代码

主要使用了column-count和column-gap属性,column-count属性用来设置列数,column-gap属性用来设置列于列之间得间距

页面的DOM结构和上种方式是一样的,主要对css样式进行了修改

* { margin: 0; padding: 0;}body { padding: 5px; background-color: lightgray;}body::-webkit-scrollbar { width: 4px; height: 1px;}body::-webkit-scrollbar-thumb { border-radius: 2px; background: #E0E0E0;}body::-webkit-scrollbar-track { border-radius: 10px; background: #FFF;}/* 使用column多列布局 *//* 主要使用了 column-count 和 column-gap 属性*/#wrap { width: 100%; height: calc(100vh - 20px); column-count: 3; /* 列数 */ column-gap: 10px; /* 列与列之间的距离 */}#wrap div { background-color: #FFF; border-radius: 8px; font-size: 40px; font-weight: bold; text-align: center; margin-bottom: 10px;}#wrap div img{ width: 100%; border-radius: 8px 8px; vertical-align: bottom;}#wrap div p{ font-size: 24px;}.item1 { height: 200px;}.item2 { height: 250px;}.item3,.item5,.item7 { height: 200px;}.item4,.item10 { height: 150px;}.item6{ height: 240px;}.item9 { height: 100px;}.item8 { height: 250px;}

实现效果如下


但是可以看到数字为7的模块被截断,然后选择放置图片看下效果


放置图片显示效果还可以,没有出现截断的情况

column-count对浏览器兼容性不是特别好,如下

flex属性实现瀑布流

首先分析下实现原理:

因为是用css的flex布局实现的,所以就没有用到js代码

将大容器(父元素)的display设置为flex,然后使用flex-flow属性,设置为:flex-flow: column wrap;

flex-flow 作用是使弹性项目按列显示,并在需要时换行

flex-flow 属性是以下属性的简写属性:

flex-directionflex-wrap

页面的DOM结构和上种方式是一样的,主要对css样式进行了修改

/* 去掉了大小容器的定位样式,将大容器设置为flex布局,并设置flex-flow属性 */* { margin: 0; padding: 0;}body { padding: 5px; background-color: lightgray;}body::-webkit-scrollbar { width: 4px; height: 1px;}body::-webkit-scrollbar-thumb { border-radius: 2px; background: #E0E0E0;}body::-webkit-scrollbar-track { border-radius: 10px; background: #FFF;}/* 去掉了大小容器的定位样式,将大容器设置为flex布局,并设置flex-flow属性 *//* flex-flow属性是 flex-direction 和 flex-wrap 属性的简写形式 flex-direction 控制元素的方向顺序 flex-wrap 控制元素在必要时折行*/#wrap { width: 100%; height: calc(100vh - 20px); display: flex; flex-flow: column wrap; }#wrap div { width: calc(100% / 3 - 20px / 3); background-color: #FFF; border-radius: 8px; font-size: 40px; font-weight: bold; text-align: center; margin-top: 10px; margin-right: calc(20px / 3)}#wrap div img{ width: 100%; border-radius: 8px 8px 0 0; vertical-align: bottom;}#wrap div p{ font-size: 24px;}.item1 { height: 200px;}.item2 { height: 250px;}.item3,.item5,.item7 { height: 200px;}.item4,.item10 { height: 150px;}.item6{ height: 240px;}.item9 { height: 100px;}.item8 { height: 250px;}}

实现的结果图如下


可以放置图片查看效果


flex-flow对浏览器的兼容性也不是特别好,但是相对column-count好一点,如下


小结: 原生js的展示是以行展示,而flex布局column布局是以列进行展示,可以根据项目需求进行选择

列数动态的瀑布流

第一种方式实现的是列数固定的布局,所以当列数可以任意指定时,上述方法就不再适用了

动态列数的DOM结构和样式和第一种方式是一样的,只有js代码略有不同

<script> let divList = $('#wrap div') divList = Array.from(divList) // 获取DOM节点,并转化为数组 let pageW = document.documentElement.clientWidth let cols = 4 // 动态设置列数 let divW = parseInt((pageW - (cols + 1) * 10) / cols) // 计算每一个容器div的宽度并取整 let arrH = [] divList.forEach((item, index) => { if (index < cols) { arrH.push(item.clientHeight) item.style.left = index * divW + index * 10 + 'px' } item.style.width = divW + 'px' // 给每一个div容器设置宽度 }) for (let i = cols; i < divList.length; i++) { let minH = Math.min.apply(Math, arrH), idx_min = arrH.indexOf(minH) divList[i].style.left = divList[idx_min].style.left divList[i].style.top = minH + 10 + 'px' arrH[idx_min] = minH + divList[i].clientHeight + 10 }</script>

实现的结果图如下


总的来说,瀑布流布局就是为了节省页面展示的空间

有看不懂的地方欢迎留言~~

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。