瀑布流布局的原理及实现,waterfall瀑布图

  瀑布流布局的原理及实现,waterfall瀑布图

  

目录

  瀑布式典型网站瀑布式布局原理总体思路具体思路插件包步骤1、步骤2、步骤3、步骤4、步骤5动态渲染需求分析渲染页面1数据渲染页面2渲染页面(手动加载)渲染页面2(滚动加载)需要特别注意的问题

  

瀑布流典型网站

  花瓣网,糖叠

  

瀑布流布局原理

  

大体思路

  首先,页面布局的特点是宽度相同,长度不同。

  可见这个布局应该是用绝对定位的思路来做的。

  以上五种正常排列。在第六个之后,将添加最短的那个。

  如何得到最短的列?

  第一个最好找。每隔一个盒子可以得到它的高度,找到最短的盒子,然后找到最短盒子的位置。

  新添加的框的位置是:

  Left:最短盒子的索引*(盒子宽度左右间距)top:放入上下间距后,这个盒子的高度发生变化。记录下来生成新的身高,然后进行下一轮身高对比。诸如此类。

  Waterful是一个组件,基于jquery的一个组件。

  

具体思路

  最外面的左右两边没有间距,所以5列的情况下有4个间距。因此,当宽度width不变时,宽度space的间距可以计算为:

  间隔

  var space=(w parent-5 * width)/(col-1);//wParent是父框的宽度,width是子框的宽度,col是第一行列中框的位置:

  Top: 0 left: index *(宽度空间)第二行中框的位置:

  top:min height space left:index *(width space)所以5列的高度要用一个数组来表示,可以找到最短的元素及其当前索引。

  

插件封装

  因为在第一次加载和第n次加载中,需要瀑布布局。所以瀑布布局的方法是用一个插件封装的,可以形成代码复用。首先,了解瀑布流的html布局。

  !-page容器- div class=container !-与顶部有距离的所有项目的集合- div class=items !-每个小块,包含图片和文字-div class= item img src= /pHello/p/div div class= item img src= /pHello/p/div/div div class= BTN 正在加载./div这是jquery的插件。

  

第一步

  在jquery中将全局变量转换为局部变量。

  防止全球污染,提高性能形成闭合。闭包中定义的变量不会影响外部变量。

  /*自调用形成一个闭包*/(function($){/*如果不加jQuery,里面用的$是全局变量;添加后是成员变量*/})(jQuery);

  

第二步

   jquery.fn.extend(对象)

  jquery中的Fn函数

  为第三方方法提供一个条目,并扩展jquery元素集()以提供新方法(通常用于制作插件)。

  /* js/jquery-瀑布图. js */(函数($) {$。fn。瀑布=function () {/*这个指向当前调用这个方法的元素集(元素集是jQuery) */console.log得到的伪数组(This);} })(jQuery);

  

第三步

  排列第一行。

  (函数($) {$。fn。瀑布=function(){//这指向当前调用此方法的元素集。//当前瀑布父容器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);//array var colHeightArr=[]记录每一列的高度;//遍历每个子元素$。each (child,function (i,item){ var $ item=$(item);var height=$ item . height();//设置定位//第一行的元素都在顶部,所以索引从0开始,if (i col) {$ item.css ({top: 0,left: i * (width space)})小于5时在顶部;//将高度添加到数组中。colHeightArr[i]=高度;//也可以使用colheightarr . push(height);}//其他都要按最短的列排列});} })(jQuery);所以你可以看到效果图(因为模拟制作了13个盒子,其余的一个叠一个)

  此时打印以下高度数组:

  您可以看到前五个的高度存储在数组中。可以判断最小的数组是289,289对应的数组的索引就是该列的索引。

  

第四步

  排列其余的行。找到最小的加法,然后增加这个列的高度。诸如此类。最大物品等于最大高度。这样,下面的载荷就可以移到底部。

  (函数($) {$。fn。瀑布=function(){//这指向当前调用此方法的元素集。//当前瀑布父容器var items=$(this);//父容器var wParent=items.width()的宽度;//当前瀑布子容器var child=items . children();//获取子容器的宽度var width=child . width();//假设排列了多少列,var col=5;//计算间距var space=(w parent-col * width)/(col-1);//array var colHeightArr=[]记录每一列的高度;//遍历每个子元素$。each (child,function (i,item){ var $ item=$(item);var height=$ item . height();//定位//第一行的元素都在顶部。//索引从0开始,if (i col) {$ item.css ({top: 0,left: i * (width space)})小于5时在顶部;//colHeightArr[I]=height;colHeightArr.push(高度);//其他的都要按照最短的列来排列}else{ //找到最短的列来排列//index var index=0;//假设最小高度是第一个索引varminheight=colheightarr[index]对应的高度;//遍历数组,找到最小值和最小值对应的索引。//k是索引,v是值$。each (colheightarr,function (k,v){ if(minheightv){ index=k;min height=v;} });//Locate $ item . CSS({ top:minheightspace,left:index *(width space)})//用当前数组中最小的高度更新新的高度。colheightarr[index]=minheightspace height;}//console . log(colHeightArr);});//设置父容器var maxHeight=colHeightArr[0]的高度;$.each(colHeightArr,function(k,v){ if(max height v){ max height=v;} });//设置父容器的最高高度items . height(max height);} })(jQuery);效果图:

  

第五步

  在HTML中调用(以上渲染图已调用)

  $(.项目)。瀑布();但是如果有图的话,这样的通话在网速慢的时候会出问题。不加载图片时排列图片,加载中间图片时,方框会重叠。

  解决方案:

  /*页面上的所有资源都是加载并布局的,否则无法得到图片的大小和框的高度*/window.onload=function () {$(。项目)。瀑布();}//为什么不用jquery,因为这种方法是在下载完dom元素之后再加载,加载完之后需要等待所有的资源都整理好。/* $(function(){//console . log( DOM loaded );});*/

  

动态渲染

  因为数据很多,所以会批量渲染。

  示意图:

  界面:

  接口描述:瀑布流分页数据

  地址:data.php

  请求方法:获取

  界面参数:当前是哪一页?

  PageSize,当前页面应该显示多少行?

  返回类型:json

  返回数据:

  {第2页,项目:[{path:。/images/1.jpg ,text:},] }

  下一页的页码(根据页码获取下一页的数据)

  Items返回当前页面的数据。

  路径图片地址

  文本文本

  这个时候就要准备壳了。

  div class=容器 div class=项目!-where - TODO需要呈现数据-/div div class= btnloading 正在加载./div/div

  

需求分析

  加载第一页时

  1.加载第一页的数据ajax

  2.需要显示该按钮才能加载更多内容

  3.artTemplate被加载并呈现到页面上。

  4.将瀑布初始化为瀑布布局

  当加载下一页时

  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();});得到如图所示的数据:

  

渲染页面

  准备模板

  的脚本类型= text/template id= template % for(var I=0;iitems.lengthI){ % div class= item img src= %=items[I]。path% alt= p%=items [I]。text %/p/div % } %/script script $(function(){//Get DOM var $ items=$(var $ BTN=$(。BTN’);//Render var Render=function(){//加载数据渲染页面瀑布布局$。Ajax ({type: get ,URL: data.php ,data: {page: 1,pagesize: 10},datatype: json ,success:function(data){ $ items . append(template( template ,data));//瀑布布局$items .瀑布();//更改按钮$ btn.removeclass (loading )。html(加载更多);} });} render();});/脚本

  

第二页面的渲染(手动加载)

  第二页需要更改的内容:

  添加按钮的click事件,点击按钮后渲染。当你点击按钮加载时,你要锁定它,因为如果你不添加它,你会发送多个ajax请求来确定按钮是否处于加载状态,如果是,你就不会渲染数据。在render函数中,当按钮状态改变时,使用自定义属性记录下一页的页码。用data()在里面上传一个页面,把data.page放进去。所以当你得到数据的时候,你应该从按钮的数据中得到page的值。它第一次是空的,所以设置默认值1。在render函数中,在数据加载成功之前,按钮还处于加载状态,所以增加了一个beforeSend函数,它处于加载状态。在render函数中,判断渲染时是否没有数据,判断返回的数组长度是否为零。如果是零,说明没有更多的数据了。$(function(){ //获取dom var $items=$(。要操作的项目);var $btn=$(。BTN’);//Render var Render=function(){//加载数据以呈现页面的瀑布式布局$。Ajax ({type: get ,URL: data.php ,data:{//取下一页的页码,如果没有则为1 page:$btn.data(page)1默认为每页,//10 pagesize: 10}在send:function(){ $ BTN . addclass( loading )之前。html(正在加载.);},数据类型: json ,成功:function(data){ console . log(data);//准备模板//因为是append,所以不能用html。应该用append //直接用数据的原因是数据是一个对象,里面有很多属性,而不是数组。数组不能这样,因为数据只有一个属性$ items . append(template( template ,data))的长度;//瀑布布局$items .瀑布();if(data . items . length){//change button//data是自定义属性,数据传来的页面保存在自定义属性$ btn.data (page ,data.page)。removeclass (loading )。html(加载更多);}else{ //无更多数据//无数据时判断。打开最后一个对象,里面的项数组长度为零$btn.addClass(loading )。html(“没有更多的数据”);} } });}//按钮加载$btn.on(click ,function(){ //为了避免发送多个ajax请求,做个判断。如果处于加载状态,则退出,if($ BTN . has class( loading ){返回false} render();})render();});

  

第二页面的渲染(滚动加载)

  说到滚动渲染,就意味着我们要从渲染的页面到浏览器底部一定距离处进行下一个请求。这需要一个判断。

  示意图:

  底层200px的时候做ajax请求。

  怎么算底?

  bottom=items的高度距items顶部的距离-向上卷曲的高度-整个浏览器的高度。

  $(function(){ //实现动态瀑布渲染//获取dom var $items=$(。要操作的项目);var $btn=$(。BTN’);//Render var Render=function(){//加载数据渲染页面瀑布布局$。Ajax ({type: get ,URL: data.php ,data:{ page:$ BTN . data( page ) 1,pagesize: 10},Before:function(){ $ BTN . addclass( loading )。html(正在加载.);},数据类型: json ,成功:function(data){ console . log(data);$ items . append(template( template ,data));//瀑布布局$items .瀑布();//判断数组中是否有数据if(data . items . length){ $ BTN . data( page ,data.page)。removeclass (loading )。html(加载更多);} else {$ btn.addclass (loading )。html(“没有更多的数据”);} } });}//滚动加载$(窗口)。on (scroll ,function(){//距文档底部的距离小于200px才能加载。//项目的高度在完成之前无法加载。items的高度var items height=$ items . height();//从顶层var items top=$ items.offset()偏移的项。顶;//整个页面到顶部卷曲出去的距离var scrolltop=$ (document)。scroll top();//浏览器的高度var winHeight=$(window)。height();//浏览器底部到items底部的距离var bottom=items height items top-scroll top-winheight;//确定按钮是否处于加载状态var loading=$ BTN . has class( loading );//如果按钮小于200且不在加载状态,开始加载If(底部200!正在加载){ render();} })渲染();});

  在

需要特别注意的问题

  之前,我们在静态加载页面时使用window.onload,这样可以在渲染页面之前加载页面上的所有资源。否则会出现页面重叠的情况。

  在动态加载页面时,我们首先获取背景数据,然后在加载img图片之前将其转换为html并添加到页面中。这里也有之前的问题。

  后面不使用window.onload的原因是原来设置的图片已经设置为宽高。一些图像设置为250像素,而另一些图像设置为450像素。但这是不合理的,因为有些画面会失真。

  下面是解决问题的方法:

  当所有图片加载完毕后,页面就会渲染出来,但是时间长,不合理。参考花瓣花瓣在加载图片时也设置了宽度和高度,但是这个尺寸要根据原图的尺寸进行缩放。

  原始大小为608,当前宽度为200,因此转换当前高度。

  当前高度=200/806 * 782

  宽度是当前宽度。

  //写img height=%=items [i]。宽度*项目[i]。高度/宽度% src=%=items [i]。path%/*还在成功的ajax中,$ items . append(template( template ,{data: data,))这样就可以使用width变量了。*/这样瀑布就完成了。

  关于瀑布瀑布布局动态渲染的实现本文到此为止。有关瀑布瀑布布局的更多信息,请搜索以前的文章或继续浏览下面的相关文章。希望你以后能支持我!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: