JavaScript实现瀑布流布局的3种方式


Posted in Javascript onDecember 27, 2020

前言

今天逛闲鱼的时候观察到每一行的高度不是相同的,经了解才知道原来这是一种瀑布流布局,感觉挺有意思,于是决定研究一下,在网上也找了一些方案,实现瀑布流大概有3种方式。

一、JS 实现瀑布流

思路分析

1、瀑布流布局的特点是等宽不等高。
2、为了让最后一行的差距最小,从第二行开始,需要将图片放在第一行最矮的图片下面,以此类推。
3、父元素设置为相对定位,图片所在元素设置为绝对定位。然后通过设置 top 值和 left 值定位每个元素。

代码实现

<!DOCTYPE html>
<html>
<head>
 <style>
 .box {
  width: 100%;
  position:relative;
 }
 .item {
  position: absolute;
 }
 .item img{
  width: 100%;
  height:100%;
 }
 </style>
</head>
<body>
<div class="box">
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
</div>
</body>
<script src="jquery.min.js"></script>
<script>
 function waterFall() {
 // 1 确定图片的宽度 - 滚动条宽度
 var pageWidth = getClient().width-8;
 var columns = 3; //3列
 var itemWidth = parseInt(pageWidth/columns); //得到item的宽度
 $(".item").width(itemWidth); //设置到item的宽度
 var arr = [];
 $(".box .item").each(function(i){
  var height = $(this).find("img").height();
  if (i < columns) {
  // 2 第一行按序布局
  $(this).css({
   top:0,
   left:(itemWidth) * i+20*i,
  });
  //将行高push到数组
  arr.push(height);
  } else {
  // 其他行
  // 3 找到数组中最小高度 和 它的索引
  var minHeight = arr[0];
  var index = 0;
  for (var j = 0; j < arr.length; j++) {
   if (minHeight > arr[j]) {
   minHeight = arr[j];
   index = j;
   }
  }
  // 4 设置下一行的第一个盒子位置
  // top值就是最小列的高度
  $(this).css({
   top:arr[index]+30,//设置30的距离
   left:$(".box .item").eq(index).css("left")
  });

  // 5 修改最小列的高度
  // 最小列的高度 = 当前自己的高度 + 拼接过来的高度
  arr[index] = arr[index] + height+30;//设置30的距离
  }
 });
 }
 //clientWidth 处理兼容性
 function getClient() {
 return {
  width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
  height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
 }
 }
 // 页面尺寸改变时实时触发
 window.onresize = function() {
 //重新定义瀑布流
 waterFall();
 };
 //初始化
 window.onload = function(){
 //实现瀑布流
 waterFall();
 }
</script>
</html>

效果如下

JavaScript实现瀑布流布局的3种方式

二、column 多行布局实现瀑布流

思路分析:

column 实现瀑布流主要依赖两个属性。
一个是 column-count 属性,是分为多少列。
一个是 column-gap 属性,是设置列与列之间的距离。

代码实现:

<!DOCTYPE html>
<html>
<head>
 <style>
 .box {
  margin: 10px;
  column-count: 3;
  column-gap: 10px;
 }
 .item {
  margin-bottom: 10px;
 }
 .item img{
  width: 100%;
  height:100%;
 }
 </style>
</head>
<body>
<div class="box">
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
</div>
</body>

效果如下:

JavaScript实现瀑布流布局的3种方式

三、flex 弹性布局实现瀑布流

思路分析:

flex 实现瀑布流需要将最外层元素设置为 display: flex,即横向排列。然后通过设置 flex-flow:column wrap 使其换行。设置 height: 100vh 填充屏幕的高度,来容纳子元素。每一列的宽度可用 calc 函数来设置,即 width: calc(100%/3 - 20px)。分成等宽的 3 列减掉左右两遍的 margin 距离。

代码实现:

<!DOCTYPE html>
<html>
<head>
 <style>
 .box {
  display: flex; 
  flex-flow:column wrap;
  height: 100vh;
 }
 .item {
  margin: 10px;
  width: calc(100%/3 - 20px);
 }
 .item img{
  width: 100%;
  height:100%;
 }
 </style>
</head>
<body>
<div class="box">
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="show.jpg" alt="" />
 </div>
 <div class="item">
 <img src="cloth.jpg" alt="" />
 </div>
 <div class="item">
 <img src="banner.jpg" alt="" />
 </div>
</div>
</body>

效果如下:

JavaScript实现瀑布流布局的3种方式

四、3种方式对比

如果只是简单的页面展示,可以使用 column 多栏布局和 flex 弹性布局。如果需要动态添加数据,或者动态设置列数,就需要使用到 JS + jQuery。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 自定义容器下雨效果可将下雨图标改为其他
Apr 23 Javascript
中文输入法不触发onkeyup事件的解决办法
Jul 09 Javascript
javascript获取dom的下一个节点方法
Sep 05 Javascript
移动端点击图片放大特效PhotoSwipe.js插件实现
Aug 25 Javascript
JavaScript中访问id对象 属性的方式访问属性(实例代码)
Oct 28 Javascript
vue点击当前路由高亮小案例
Sep 26 Javascript
js中的面向对象之对象常见创建方法详解
Dec 16 Javascript
浅谈Vue 函数式组件的使用技巧
Jun 16 Javascript
微信小程序 button样式设置为图片的方法
Jun 19 Javascript
JS出现404错误原理及解决方案
Jul 01 Javascript
详解vue路由
Aug 05 Javascript
nuxt.js 在middleware(中间件)中实现路由鉴权操作
Nov 06 Javascript
Vue实现省市区三级联动
Dec 27 #Vue.js
JavaScript实现通讯录功能
Dec 27 #Javascript
vue3.0自定义指令(drectives)知识点总结
Dec 27 #Vue.js
vue 使用 sortable 实现 el-table 拖拽排序功能
Dec 26 #Vue.js
在vue项目中封装echarts的步骤
Dec 25 #Vue.js
vue中封装axios并实现api接口的统一管理
Dec 25 #Vue.js
Vue 简单实现前端权限控制的示例
Dec 25 #Vue.js
You might like
《Re:从零开始的异世界生活》剧情体验,手游新作定名
2020/04/09 日漫
相对路径转化成绝对路径
2007/04/10 PHP
解析PHP中的file_get_contents获取远程页面乱码的问题
2013/06/25 PHP
php计算两个坐标(经度,纬度)之间距离的方法
2015/04/17 PHP
Laravel实现批量更新多条数据
2020/04/06 PHP
Js放到HTML文件中的哪个位置有什么区别
2013/08/21 Javascript
JavaScript中的正则表达式简明总结
2014/04/04 Javascript
node.js中的fs.open方法使用说明
2014/12/17 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记6)
2015/12/20 Javascript
玩转JavaScript OOP - 类的实现详解
2016/06/08 Javascript
JavaScript中对象的不同创建方法
2016/08/12 Javascript
关于List.ToArray()方法的效率测试
2016/09/30 Javascript
JavaScript设置名字输入不合法的实现方法
2017/05/23 Javascript
Bootstrap Table从零开始
2017/06/30 Javascript
基于input框覆盖掉数字英文的实例讲解
2017/07/21 Javascript
详解在vue-cli项目中使用mockjs(请求数据删除数据)
2017/10/23 Javascript
jQuery进阶实践之利用最优雅的方式如何写ajax请求
2017/12/20 jQuery
nodejs 使用 js 模块的方法实例详解
2018/12/04 NodeJs
javascript实现计算指定范围内的质数示例
2018/12/29 Javascript
详细讲解如何创建, 发布自己的 Vue UI 组件库
2019/05/29 Javascript
js实现从右往左匀速显示图片(无缝轮播)
2020/06/29 Javascript
Python简单计算文件夹大小的方法
2015/07/14 Python
Linux下通过python访问MySQL、Oracle、SQL Server数据库的方法
2016/04/23 Python
python 3.3 下载固定链接文件并保存的方法
2018/12/18 Python
Django中使用CORS实现跨域请求过程解析
2019/08/05 Python
python数据分析:关键字提取方式
2020/02/24 Python
python GUI库图形界面开发之PyQt5表格控件QTableView详细使用方法与实例
2020/03/01 Python
使用 HTML5 Canvas 制作水波纹效果点击图片就会触发
2014/09/15 HTML / CSS
基于Html5实现的语音搜索功能
2019/05/13 HTML / CSS
入党自我鉴定
2014/03/25 职场文书
入党积极分子批评与自我批评思想汇报
2014/09/14 职场文书
迎国庆横幅标语
2014/10/08 职场文书
AI:如何训练机器学习的模型
2021/04/16 Python
使用vue-element-admin框架从后端动态获取菜单功能的实现
2021/04/29 Vue.js
Python3中最常用的5种线程锁实例总结
2021/07/07 Python
Centos7中MySQL数据库使用mysqldump进行每日自动备份的编写
2021/08/02 MySQL