您现在的位置是:网站首页> 编程资料编程资料
waterfall瀑布流布局+动态渲染的实现3种方式实现瀑布流布局小结详解纯css实现瀑布流(multi-column多列及flex布局)css3 column实现卡片瀑布流布局的示例代码用CSS3实现瀑布流布局的示例代码CSS3实现瀑布流布局与无限加载图片相册的实例代码瀑布流布局的两种实现方式:传统多列浮动和绝对定位布局
2023-10-17
360人已围观
简介 这篇文章主要介绍了waterfall瀑布流布局+动态渲染的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
瀑布流典型网站
花瓣网、堆糖
瀑布流布局原理
大体思路
首先先是页面布局 特点是:宽度一样,长度不一样

由此可以知道,这种布局要用到 绝对定位 的思想来做。
上面的五个正常排列,到了第六个以后就要找最矮的追加了。
如何获取最矮的一列呢?
第一个最好找,其他的每一个盒子可以获取它的高度,找最矮的盒子,然后找到最矮盒子的定位。
新追加进去的盒子的定位是:
- left:最矮盒子的索引*(盒子的宽度+左右间距)
- top: 这个盒子的高度 + 上下间距
放进去之后这一列的高度变化,记录下来生成新的高度,然后进行下一轮高度的比较。以此类推。
waterful 是一个组件,基于 jquery 的一个组件。
具体思路

最外边的左右两边是没有间距的,所以 5 列的情况下有 4 个间距。所以宽度 width 一定的情况下,间距的宽度 space 是可以计算出来的:
间距
var space = (wParent - 5 * width) / (col - 1); // wParent 父盒子的宽度,width是子盒子的宽度,col是列数
第一排的盒子的定位:
- top : 0
- left : 索引*(width + space)
第二排的盒子的定位:
- top : minHeight + space
- left : 索引*(width + space)
所以 5 列的高度要用一个数组表示,可以找到最矮的元素以及其当前的索引。
插件封装
因为在第一次加载和第 n 次加载的时候,都要进行瀑布流布局。所以将瀑布流布局的方法进行一个插件进行封装,可以形成代码的复用。 首先了解瀑布流的 html 布局
hello
hello
正在加载...
下面就来封装一个 jquery 的插件
第一步
将 jquery 中的全局变量转化为局部变量。
防止全局污染,提高性能 形成一个闭包,闭包里面定义的变量是不会影响外部变量的。
/*自调用 形成一个闭包 */ (function($){ /*如果不加jQuery里面使用的$是全局变量,加了之后使用的就是成员变量*/ })(jQuery);第二步
jquery.fn.extend(object)
jquery 中的 fn 函数
提供一个第三方方法的一个入口,扩展 jquery 元素集(使用 $ 可以获取到的元素) 来提供新的方法(通常用来制作插件)
/*js/jquery-waterfall.js*/ (function($){ $.fn.waterfall = function(){ /*this指向的是当前调用这个方法的元素集(元素集是jquery获取元素是一个伪数组)*/ console.log(this); } })(jQuery);第三步
对第一排进行排列
(function($){ $.fn.waterfall = function(){ // this指向的是当前调用这个方法的元素集 // 当前的瀑布流父容器 var items = $(this); //父容器的宽度 var wParent = items.width(); //当前的瀑布流子容器 var child = items.children(); //获取子容器的宽度 var width = child.width(); //假设排多少列 var col = 5; //计算间距(父元素的宽度减所有盒子的宽度/4) var space = (wParent - col * width) / (col - 1); //记录每列高度的数组 var colHeightArr = []; //遍历每一个子元素 $.each(child,function(i,item){ var $item = $(item); var height = $item.height(); //设置定位 //第一排的元素都是靠顶部的,所以索引从0开始,小于5的时候都是靠顶部的 if(i < col ){ $item.css({ top: 0, left:i * (width + space) }); //把高度添加进数组中 colHeightArr[i] = height; //也可以用 colHeightArr.push(height); } //其他的都要根据最矮的一列进行排列 }); } })(jQuery);这样你就看到了效果图(因为模拟做了 13 个盒子,所以剩下的叠在了一起)

这个时候打印以下高度数组:

可以看到前 5 个的高度都存到数组中去了。可以判断出来数组中最小的是 289 , 289 对应的数组的索引就是那一列的索引。
第四步
对其余的排进行排列。找最小的追加,然后本列的高度增加。以此类推。 最大的 items 等于最大的高度。这样才可以把下面的加载移动到下边去。
(function($){ $.fn.waterfall = function(){ // this指向的是当前调用这个方法的元素集 // 当前的瀑布流父容器 var items = $(this); //父容器的宽度 var wParent = items.width(); //当前的瀑布流子容器 var child = items.children(); //获取子容器的宽度 var width = child.width(); //假设排多少列 var col = 5; //计算间距 var space = (wParent - col * width) / (col - 1); //记录每列高度的数组 var colHeightArr = []; //遍历每一个子元素 $.each(child,function(i,item){ var $item = $(item); var height = $item.height(); //定位 //第一排的元素都是靠顶部的 //索引从0开始,小于5的时候都是靠顶部的 if(i < col ){ $item.css({ top: 0, left:i * (width + space) }); //colHeightArr[i] = height; colHeightArr.push(height); //其他的都要根据最矮的一列进行排列 }else{ //找到最矮的那一列进行排列 //索引 var index = 0; //假设最小的高度是第一个索引对应的高度 var minHeight = colHeightArr[index]; //遍历数组,找到最小值和最小值对应的索引 //k是索引,v是值 $.each(colHeightArr,function(k,v){ if(minHeight > v){ index = k; minHeight = v; } }); //定位 $item.css({ top:minHeight + space, left:index * (width + space) }) //当前数组中最小的高度进行新的高度的更新 colHeightArr[index] = minHeight + space + height; } //console.log(colHeightArr); }); //设置父容器的高度 var maxHeight = colHeightArr[0]; $.each(colHeightArr,function(k,v){ if(maxHeight < v){ maxHeight = v; } }); //给父容器设置最高的高度 items.height(maxHeight); } })(jQuery);效果图:

第五步
html 中调用(上面的效果图都是已经调用过的)
$(".items").waterfall();但是如果有图片的话,这样调用在网络比较慢的情况下会出现问题。在图片没有加载出来的时候排列,中间图片加载完毕会造成盒子重叠的效果。
解决办法:
/*页面上所有的资源都加载完成后进行布局,否则获取不到图片的尺寸撑不开盒子的高度*/ window.onload = function(){ $(".items").waterfall(); } //为什么不用jquery的,因为这个是在dom元素下载完毕之后进行加载这个方法,需要等所有的资源加载完之后进行排列 /* $(function(){ //console.log('dom loaded'); }); */动态渲染
因为数据很多,所以会进行分批次渲染。
原理图:

接口文档:
接口说明: 瀑布流分页数据
接口地址:data.php
请求方式:get
接口参数:page 当前是第几页
pageSize 当前页要显示多少条
返回类型:json
返回数据:
{ page:2,items:[{path:"./images/1.jpg",text:'''},...] }
page 下一页的页码(根据页码获取下一页的数据)
items 返回当前页的数据
path 图片地址
text 文字
此时我们要准备好壳子
正在加载中...
需求分析
加载第一页的时候
1.加载第一页的数据 ajax
2.按钮需要显示成加载更多
3.加载完成渲染到页面当中 artTemplate
4.初始化成瀑布流布局 waterfall
加载下一页的时候
1.加载数据
- 手动加载:点击按钮加载下一页的数据
- 自动加载:滚动到底部的时候主动加载下一页
2.按钮需要显示 “正在加载中...” 不能点击 防止重复提交
3.加载完成渲染到页面当中
4.初始化成瀑布流布局
5.按钮需要显示成加载更多
没有更多数据把按钮禁用 显示 “没有更多数据了”
渲染第一页数据
发送请求
既然加载页面的时候都会用到加载数据、渲染页面、初始化瀑布流,就把这三个动能封装到一个函数中去,先实现第一个功能:
$(function(){ //实现动态的瀑布流渲染 //渲染 var render = function(){ // 加载数据 渲染页面 瀑布流布局 $.ajax({ type:'get', url:'data.php', data:{ //第一页 page:1, //每页10条 pageSize:10 }, dataType:'json', success:function(data){ console.log(data); } }); } render(); }); 拿到的数据如图:

渲染页面
准备模板
第二页面的渲染(手动加载)
第二页需要改变的东西:
- 添加按钮的点击事件,点击按钮之后就进行渲染。
- 点击按钮加载的时候,要给按钮加锁,因为不加的话会发送多个ajax请求,判断按钮是不是loading状态,如果是的话就不渲染数据。
- render函数中,在进行按钮状态改变的时候,用自定义属性记录下来下一页的要获取的页数。利用data(),里面传一个page,把data.page放进去。所以在拿数据的时候,要从按钮的data中获取page的值。第一次是空的,所以就设定一个默认值为1
- render函数中在数据成功加载之前,按钮还是loading状态,所以加一个beforeSend的函数,里面是loading状态。
- render函数中在渲染的时候判断一下是不是没有数据了,根据返回的数组中的长度是不是为零来判断,如果是零的话就显示没有更多数据了。
$(function(){ //获取需要操作的dom var $items = $(".items"); var $btn = $(".btn"); //渲染 var render = function(){ // 加载数据 渲染页面 瀑布流布局 $.ajax({ type:'get', url:'data.php', data:{ //取下一页的页码,没有的话就默认是1 page:$btn.data("page")||1, //每页10条 pageSize:10 }, beforeSend:function(){ $btn.addClass("loading").html('正在加载中...'); }, dataType:'json', success:function(data){ console.log(data); //准备模板 //因为是追加所以不能用html,要用append //直接用da
相关内容
- CSS 奇思妙想边框动画效果的实现一文教你玩转CSS border(边框)CSS3 按钮边框动画的实现CSS3 实现发光边框特效两款纯CSS3鼠标经过按钮边框动画特效一篇文章带你学习CSS3图片边框css3多种边框悬停按钮填色动画特效css 透明边框background-clip妙用CSS3实现缺角矩形,折角矩形以及缺角边框CSS边框长度控制功能的实现CSS实现半透明边框与多重边框的场景分析
- CSS 动态高度过渡动画效果的实现CSS实现漂亮的时钟动画效果的实例代码css3动画鼠标放上图片逐渐变大鼠标离开图片逐渐缩小效果CSS 奇思妙想边框动画效果的实现使用CSS3制作版头动画效果CSS3分享图标按钮动画特效代码CSS3通过var()和calc()函数实现动画特效
- 龙纹三国彩蝶秘境资料详细介绍_手机游戏_游戏攻略_
- 金克斯升空闪退黑屏的解决方法_手机游戏_游戏攻略_
- 神雕侠侣关于五倍经验丹的使用分析_手机游戏_游戏攻略_
- 神雕侠侣师门任务攻略详细介绍_手机游戏_游戏攻略_
- 神雕侠侣科举题库答案大全_手机游戏_游戏攻略_
- 天天飞车无限隐身无限combo刷分攻略_手机游戏_游戏攻略_
- 屌丝自传 第2-1关为鲜花上色 图文攻略_手机游戏_游戏攻略_
- 屌丝自传 第2-2关屌丝向前冲 图文攻略_手机游戏_游戏攻略_
点击排行
本栏推荐
