宝哥软件园

jQuery (PC和手机)实现瀑布流布局详解

编辑:宝哥软件园 来源:互联网 时间:2021-09-28

瀑布流布局已经成为一种非常常见的图片显示方式,无论是在PC还是手机等移动设备上。这个布局图有三种风格:等宽、等宽不等高、等宽不等高。接下来我们就以最常见的等宽不等高的形式为例。

我们以百度图片为例:

这是PC端常见的瀑布流布局。接下来,让我们回顾一下元素,看看百度图片是如何布局的:

可以看到实际上有几个等宽的列容器,通过计算将图片推入不同的容器中。本文介绍的呈现方式是通过定位。虽然最终的布局呈现不同,但之前的算法是相似的。

开始工作

首先,我们将以下样式的几个单元写入正文,并向左浮动“框”:

div class=' box ' img class=' img ' src=' http :/resource/images/1 . jpg/' div class=' desc ' description/div/div class=' box ' img class=' img ' src=' http :/resource/images/2 . jpg/' Div class=' desc ' description/Div/Div class=' box ' img class=' img ' src=' http :/resource/images/3 . jpg '/div class=' desc ' description/div/div具有以下效果:

下一步:

var boxArr=$('。box '),num=math . floor(document . body . client width/BoxArr . eq(0)。outwidth(true)),columnHeightArr=[];columnHeightArr.length=numboxArr.each(函数(索引,项){ if(索引号){ columnHeightArr[index]=$(项)。外部高度(真);} else { var minhAiR=Math . min . apply(null,columnHeightArr),minHeightIndex=$。inar ray(minhAiR,columnHeightArr);$(物品)。css({ position: 'absolute ',top: minHeight,left : BoxArr . eq(minhAiR index)。位置()。左});}});以上代码如下:

1.首先,计算浏览器中一行可以容纳多少图片(num),注意这里使用的是outerWidth。当传入true时,将返回所有盒子模型属性的尺寸,包括边距、填充和边框;

2.创建一个数组存储每列的高度,数组的长度为num值;

3.遍历所有图片,将第一行的图片高度存储在列高数组中,从第二行开始计算最小高度和最小高度所在的列。之后,将图片放在高度最小的那一列下面第二行的开头,效果如下:

可以看到,所有的图片虽然放在正确的地方,但是都放在了同一个地方,因为我们需要在放置图片后增加柱的高度:

var boxArr=$('。box '),num=math . floor(document . body . client width/BoxArr . eq(0)。outwidth(true)),columnHeightArr=[];columnHeightArr.length=numboxArr.each(函数(索引,项){if(索引号){columnHeightArr[index]=$(项)。外部高度(真);} else { var minhAiR=Math . min . apply(null,columnHeightArr),minHeightIndex=$。inar ray(minhAiR,columnHeightArr);$(物品)。css({ position: 'absolute ',top: minHeight,left : BoxArr . eq(minhAiR index)。位置()。左});columnHeightArr[minhArthindex]=$(项)。外部高度(真);}});结果是正确的:

注意:以上代码需要在window.onload方法中运行,因为每个图片的高度只有在页面中的图片资源全部加载后才会生效。

因此,会出现一些严重的问题。网络不好的时候,图片不会满载,图片显示不完整,高度缺失,在移动端明显。而当我们加载更多的时候,就更难判断新添加的图片是否加载了。

在实际生产中,不会发生图片一开始就用HTML死写的情况,所以我们通常采用以下方式:

首先我们在得到图片地址的时候,还需要得到图片的宽度和高度,对于服务器背景来说并不难。请后台兄弟把图片的宽高数据拼成JSON传给你。

*接下来我介绍一个小技巧,非常实用。它可以保证一个元素无论变化多大或多小,比例始终保持一致。这种技术特别适合移动,因为元素通常使用百分比的形式来表示响应。

如果手机页面上有图片,它的宽度应该是屏幕的一半,长宽比应该是2:1,这在任何手机上都应该保持不变。怎么做?为元素设置以下属性:box { width : 50%;高度: 0;填充-底部: 100%;}填充不是设置高度,而是用来“挤出”元素高度,填充的百分比值基于父容器的宽度。填充物需要挤压多少?宽度乘以长宽比(宽度和填充都是百分比值),这就是为什么我们需要得到图片大小。

效果:

可以看出,ipone4和肾6Plus在chrome手机模拟器中的显示效果完全一样。在手机页面中,宽度是固定的,而高度会随着页面的内容而变化。该技术基于元素父容器的宽度使用元素的填充百分比值,并巧妙地将高值转换为与宽度相关的值。

现在,有些人可能终于忍不住要问,这和瀑布有什么关系?总之,我们应该放弃img标签,转而使用背景图像。为了使用背景图片,需要保持元素的比例始终与图片一致。

这样就可以直接生成一些和图片比例相同的div,不用判断所有图片都加载了,然后为它们设置一个背景图片,如下:

比如这里最外面的盒子宽度是220px,里面的img元素宽度可以是100%,高度可以用填充的方式挤出。

按需装载

使用背景图像的另一个优点是便于实现惰性加载。什么是懒加载?也就是当元素在我们的视野中时,图片会显示出来,但是滚动时屏幕底部的图片不会显示出来,可以大大增加加载速度,提升体验。

首先,我们将一个box-item类名添加到最外面的框中(这在后面会很有用),并不是将图像url分配给backgroundImage属性,而是分配给一个自定义属性:data-src。

div class=' box box-item ' div class=' img ' data-src=' http :/resource/images/1 . jpg '/div div class=' desc ' description/div/div接下来,我们编写惰性加载函数:

函数lazyLoad() {var boxArr=$('。方框项目');boxArr.each(函数(索引,项目){var viewTop=$(项目))。偏移量()。top - $(窗口)。scrollTop(),imgObj=$(item)。查找('。img ');if ((viewTop $(窗口))。高度())($(项)。偏移量()。top $(项目)。外部高度(真))$(窗口)。scroll top())){ imgobj . CSS(' background image ',' url(' imgObj.attr('data-src ')')')。remove CLaSS(' data-src ');$(物品)。remove CLaSS(' box-item ');}})}首先,我们得到类名为的所有元素。盒-项目和遍历。ViewTop是图片相对于浏览器窗口的相对高度,类似于position:fixed的感觉。

根据条件判断,只有当图片在浏览器窗口中(上方或下方)时,才会显示要设置的背景图片元素的data-src值,并删除属性。

之后删除最外层元素的框项,因为显示的图片不需要重新判断,删除这个类名也不会得到显示的元素,遍历的次数会越来越少,可以起到优化的作用。

当您的元素被追加到页面中并且滚动时,需要调用此函数:

lazy load();$(窗口)。卷轴(LazyLoad);

轧制负荷

懒加载之后,再来说说滚动加载。滚动加载意味着当页面滚动到接近底部时加载新图片。我这里选择的是滚动到最小高度的列底部时加载新数据,也可以根据自己的喜好来判断。

函数scrolLoad(){ var viewHeight=$(window)。scrollTop() $(窗口)。height(),minhAiR=Math . min . apply(null,columnHeightArr);if(view height=Minh heart){//load more.}}滚动加载也在窗口的滚动事件中监控,并且可以与惰性加载一起执行:

$(窗口)。scroll(function(){ scrolLoad();惰性加载();});说完了个人电脑端,我们来说下手机端。其实原理是一样的,只是从多列变成固定的两列了。

var boxArr=$(' .box '),columnHeightArr=[];columnheightarr。长度=2;boxArr .每个(函数(索引,项){if(索引2) {columnHeightArr[index]=$(项)。外部高度(真);} else { var minhAiR=Math。量滴apply(null,columnHeightArr),minHeightIndex=$ .inar ray(minhAiR,columnHeightArr);$(物品)。css({ position: 'absolute ',top: minHeight,left : BoxArr。空气指数.位置()。左});columnHeightArr[minhArthindex]=$(项)。外部高度(真);}});不同的是为了适应不同屏幕的手机,最外层的包厢容器宽度和边距要设置成百分比的形式。

最后有一点要注意,因为我们没有像百度一样用一个个列盒子去装,而是用定位的方式。导致的问题是图片元素的父级没法自适应高度,如果你有相关的需求我们可以计算出所有列中最长的长度,并将这个值赋值给父容器的最小高度属性:

$(“正文”).CSS(' minhAiR ',Math.max.apply(null,columnHeightArr));

整理下完整的代码,瀑布流的全套服务就到这了

var dataArr=[ {picUrl: ' ./resource/images/1.jpg ',width:522,height:783},{ picUrl: ' ./resource/images/2.jpg ',width:550,height:786},{ picUrl: ' ./resource/images/3.jpg ',width:535,height:800},{ picUrl: ' ./resource/images/4.jpg ',width:578,height:504},{ picUrl: ' ./resource/images/5.jpg ',宽度:1440,高度:900 }];$.每个(dataArr,函数(索引,项){ $(“body”).追加(' div class=' box box-item ' ' ' div class=' img ' style=' height :0;padding-bottom : ' CREAte(item)* 100% ' ' ' data-src=' http : ' item。picurl ' '/div ' ' div class=' desc ' description/div ' '/div ');});var boxArr=$(' .box '),num=数学。楼层(文件。尸体。客户端宽度/BoxArr。等式(0).outwidth(true)),columnHeightArr=[];columnHeightArr.length=num排列();$(“正文”).CSS(' minhAiR ',Math.max.apply(null,columnHeightArr));惰性加载();函数排列(){ boxArr .每个(函数(索引,项){ if(索引号){ ColumnHeightArr[索引]=$(项)。外部高度(真);} else { var minhAiR=Math。量滴apply(null,columnHeightArr),minHeightIndex=$ .inar ray(minhAiR,columnHeightArr);$(物品)。css({ position: 'absolute ',top: minHeight,left : BoxArr。空气指数.位置()。左});columnHeightArr[minhArthindex]=$(项)。外部高度(真);} });}函数lazyLoad() { var boxArr=$(' .方框项目');boxArr .每个(函数(索引,项目){ var viewTop=$(项目))。偏移量()。top - $(窗口)。scrollTop(),imgObj=$(item).查找('。img ');if ((viewTop $(窗口))。高度())($(项)。偏移量()。top $(项目)。外部高度(真)$(窗口)。滚动顶部())){//控制台。日志($(项).attr(' data-src ');imgObj.css('backgroundImage ',' url(' imgObj.attr('data-src ')')').移除CLaSS(' data-src ');$(物品)。移除CLaSS(' box-item ');} }) }函数板条箱{返回。高度/物体。宽度;}函数scrolLoad(){ var view height=$(window).scrollTop() $(窗口)。身高(),闵航=数学。量滴应用(null,columnHeightArr);if(视图高度=minhThEr){//加载更多.} } $(窗口)。scroll(function(){ LazyLoad();scrolLoad();});以上就是为大家分享的关于jQuery瀑布流布局,内容很丰富,需要大家一点点的理解消化,真正的做到学以致用,希望能够帮助到大家。

更多资讯
游戏推荐
更多+