html瀑布流视频列表,实现列表瀑布流布局(纯css或js定位)

本文介绍了如何使用CSS实现瀑布流布局的列表,并针对动态加载进行了优化,通过JS计算元素高度和绝对定位确保加载新数据时保持布局稳定。在遇到列表分页加载导致的重排问题时,作者提出了一种解决方案,利用定时器和uni-app的API进行元素高度计算和动态定位,从而避免列表重排,实现了良好的用户体验。

前言:最近项目好几个都怼到一起,导致好久没有更新了。这里就简单记录下这段时间常常要写的瀑布流列表

纯css实现:

直接上代码

.post-list{/* 列表设置,2列;列间距4*/

-webkit-column-count: 2;

-webkit-column-gap:16upx;

padding: 30upx 16upx;

.post-li{

-webkit-column-break-inside: avoid;/* 单个设置*/

}

}

效果:竖向排列,并且在排列中,会尽量使得两列的高度相近

4aab9fb0c202

竖向排列.png

所以这样的实现并不能用于列表分页加载。。。每次加载新页面,会使得整个列表重排。。。。

js动态排序:

还是用最近一直在写的uni-app写的,通过获取元素的高度进行绝对定位

还是上代码(数据)

data(){

return {

mescroll: null, //目前在用的上拉组件(别的组件也一样,原理基本相似)

upOption:{ //上拉组件配置

page: {

size: 6 // 每页数据的数量,默认10

},

},

list:[], //列表数据

mark: 0, // 定位

loadingTop: 0, //mescroll数据占位高度

boxHeight: [] // 计算盒子 2 行的高度

}

}

代码(方法)

列表中的每个item为绝对定位,首先都是top:0;left:0;

为这边设置为2列,所以第二列的left:50%;

至于每个item边距,我承认自己很鸡贼地用了border(并且设置border-box),具体看下面代码

第一行:top为0

其他行:算出当前最短列的高度,从而获得item绝对定位高度(因为border的缘故,也不需要担心会和上面的item粘在一起)

因为是2列,所以给其中一列加个属性left=1;在加载时判断left==1时,添加style:left:50%;

methods:{

/*上拉加载的回调*/

upCallback(mescroll) {

let param = {"pageSize":mescroll.size,"nowPage":mescroll.num}

apiGetForum(param).then(res=>{

if(mescroll.num==1) { //在列表重新加载第一页时清空相关数据(下拉刷新时,以及tab切换时)

this.list = [];

this.loadingTop = 0;

this.boxHeight=[]

}

this.mark = (mescroll.num-1) * mescroll.size // 每次只计算新加载的数据

if(res.infos) { //新的数据

this.list = this.list.concat(res.infos);

mescroll.endBySize(res.infos.length, res.total)

this.$nextTick(function(){

setTimeout(()=>{ //uni.createSelectorQuery()是异步的,最好setTimeout一下

uni.createSelectorQuery().selectAll('.post-li').boundingClientRect().exec(res => {

let item = res[0];

let len = item.length;

for (let i = this.mark; i < len; i++) {

let height = parseInt(item[i].height); //获取每个item高度

let boxHeight = height;

if (i < 2) { // 第一列

this.$set(this.list[i], 'top', 0);

this.$set(this.list[i], 'left', i);

this.boxHeight.push(boxHeight);

this.loadingTop = this.boxHeight[0]>this.boxHeight[1]?this.boxHeight[0]:this.boxHeight[1]

} else { //其他列,获取当前最数组中最小高度和它的索引

let minHeight = this.boxHeight[0];

let boxLen = this.boxHeight.length;

let index = 0;

for (var j = 0; j < boxLen; j++) {

if (minHeight > this.boxHeight[j]) {

minHeight = this.boxHeight[j];

index = j;

}

}

//设置下一行的第一个盒子位置, top值就是最小列的高度

this.$set(this.list[i], 'top', this.boxHeight[index]);

this.$set(this.list[i], 'left', index);

//修改最小列的高度 = 当前自己的高度 + 拼接过来的高度

this.boxHeight[index] = this.boxHeight[index] + boxHeight;

this.loadingTop = this.boxHeight[index];

}

//这里是为了图片加载,在刚获取到数据时,七牛处理成模糊的图,只为列拿到item的高度,排序完成后,图片改成清晰的

this.$set(this.list[i], 'isLoad', true);

}

});

},120)

})

} else{

mescroll.endBySize(0,0)

}

}).catch(()=>{

mescroll.endErr()

})

},

//获取图片

getImg(str,isLoad,type){ //this.$getImgUrl()是封装的七牛图片拼接压缩的方法,不赘述

let arr

let newUrl

if (str.indexOf('[')>-1&&str.length>2) {

arr = JSON.parse(str)

newUrl = this.$getImgUrl(arr[0])

if(isLoad){

if(type==1) { //视频直接返回

return newUrl

} else { //清晰图

return this.$getImgUrl(newUrl,300)

}

} else{//模糊的图,我测试列一下,图片大小是300字节左右

return this.$getImgUrl(newUrl,10)

}

} else {

return str

}

}

}

代码(上一下我鸡贼的css吧),实现列表距离外边框 8upx; 每个item相距16upx

view{box-sizing: border-box;}

.post-list{

position: relative;

width: 100%;

height: 100%;

border: 8upx solid #f8f8f8;

.post-li{

position: absolute;

left: 0;

width: 50%;

background: #fff;

border: 8upx solid #f8f8f8;

border-radius: 8upx;

&.left{

left: 50%;

}

}

}

效果

4aab9fb0c202

目前效果.png

好啦,完成!撒花花~~~

还有需要完善的地方,请大家指教~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值