当前位置: 首页 > Web前端 > JavaScript

瀑布布局原理解析

时间:2023-03-27 17:23:06 JavaScript

前言上篇文章讲了图片,这里说说一个常用的图片场景:Waterfall,它的实现和优化是什么Waterfall瀑布,又称瀑布布局。是一种比较流行的网站页面布局,其视觉表现是不均匀的多栏布局。随着页面滚动条的向下滚动,这个布局会不断加载数据块,并追加到当前尾部。最早采用这种布局的网站是Pinterest,后来逐渐在中国流行起来。国内大部分的新鲜站基本都是这种风格。更直观的展示如下图所示:优缺点优点:外观漂亮,更具艺术感。用户浏览时的观看和思考不易被打断,更容易留存。缺点:用户无法了解内容的总长度,无法对内容进行宏观控制。用户无法知道他现在在哪里,或者他离终点有多远。回溯时,不容易定位到之前看到的内容。容易造成页面加载负载。用户浏览很容易产生疲劳,没有短暂的休息时间。实现方案纯CSS实现这里介绍一下CSS属性:column现在常用的列属性包括这些column-count将一个元素的内容分成指定数量的列。epidemic被设置为一个特定的数字,或者autocolumn-fill控制元素的内容在被分成多列时如何平衡。有auto和balance两个值,分别代表自动填充和横向分配。column-gap两列之间的距离可以设置:px,percentage,remcolumn-rule在列布局中,分界线的设置可以设置样式,宽度,颜色(与border参数相同)column-span列布局中水平占据的元素,具体作用可以看这里column-width每一列的最小宽度,如果外部easywidth特别小,会失效另一个CSS属性columns他是用来设置的元素的列宽和列号属性。它是由列宽和列数属性组合而成的简写属性。关于兼容性,目前兼容性还不错,大部分情况下都能用。CSS相关属性更多详情请点这里提供我使用columns的demo,预览图:在线查看地址:https://grewer.github.io/JsDe...(_可以放大查看其效果浏览器_)js的实现我们也可以通过js实现瀑布流。核心思想是:我们固定每张图片的宽度,比如200px,这样我们通过步骤1的计算就可以计算出当前屏幕有N张图片,我们创建一个高度数组来存储高度遍历图像每一列,并在第2步中找到高度数组的最小值(默认为0),以便我们在相应的序号处插入图像,并在高度数组中更新其高度。具体实现步骤1和2中的初始化和高度数组constwidth=200;//默认设置为200px的宽度constcolumns=Math.floor(window.innerWidth/200)//计算当前页面的列数constcolumnsHeightArr=[]//mock图片地址consturls=newArray(10).fill(0).map((it,index)=>{return`https://grewer.github.io/JsDemo/waterfallLayout/imgs/img_${index}.png`})获取高度时图片,我们需要注意的是,当图片未加载时,获取图片的高度是不可能的,所以这里我们先加载图片,等所有图片加载完成后再计算高度。letflag=0constgetImg=(url)=>{letimg=newImage();图像。源代码=网址;constimgCallback=()=>{flag++;if(flag===urls.length){handler();}}//是否缓存if(img.complete){imgCallback()}else{img.onload=imgCallback}}所有图片加载完成后,进入handler函数,正式操作图片://添加一张图片到容器中,执行constappendImages=(url,position,top)=>{constimg=文档.createElement('img');img.src=网址;img.style.left=(position*width)+'px';img.style.top=top+'px';container.appendChild(img)returnimg}//获取高度数组中的最小高度constgetMin=(arr)=>{letminHeight=arr[0];让index=0for(leti=1;i{for(leti=0;i{if(!urls||urls.length<=0){console.log('doneallloaded')return}//如果连续有N张图片,我们将N作为批量加??载的图片数量constarr=urls.splice(0,列)letflag=arr.length;arr.forEach(async(item,i)=>{if(columnsHeightArr.length{data.forEach((item,i)=>{constimg=document.createElement('img');img.src=item.url;constheight=((item.height/item.width)*(200-gap))+gap;if(columnsHeightArr.length