图片瀑布流
需求:一个数组里的图片按两列排列,图片尺寸不一样。
问题:如果只是简单的数组分成两个数组,有可能一组图片高度加起来远远高于另一组,视觉效果太差。
想了想简单的js实现逻辑:
1、一个图片数组arr_imgs,定义左右两个盒子div
2、定义两个空数组:arr_l、arr_r(后续动态的往里面push图片项)
3、左右两个盒子里面各有一个span(这个span的作用是用来定位到页面顶部的距离,除了span其他的dom节点都行)
4、循环图片数组arr_imgs,每次循环,计算两个span距离顶部的高度,左=右或者左<右,该次循环图片项push到arr_l数组,反之push到arr_r数组。
5、两个数组arr_l、arr_r放在各自的左右盒子里,注意span要在这两个数组循环出来的dom下边呀,要不然没法把span往下撑呀。
嗯,自己写原生不是不能写,麻烦,还是找轮子吧,啊哈哈哈哈~~~
嗯~,找到了,真香
一款轻量级的js库——Macy
官方是这么说的:
Macy.js is a lightweight dependency-free JavaScript library designed to sort items vertically into columns by finding an optimum layout with a minimum height.
嗯~,差不多是这个意思。
上代码(React哦):
import React, { Component } from 'react';
import Macy from 'macy'
export default class ListImg extends Component {
state={
dataImages:["很多图片项哦"]
}
//实现瀑布流的方法啊
getMacy = () => {
if (this.state.masonry) {
this.state.masonry.reInit()
} else {
let masonry = new Macy({
container: '.macy-container', // 图像列表容器
trueOrder: false,
waitForImages: false,
useOwnImageLoader: false,
debug: true,
margin: { x: 10, y: 15 }, // 设计列与列的间距
columns: 2, // 设置列数
})
this.setState({ masonry })
}
}
render(){
const {dataImages} = this.state;
return(
// 这个类名macy-container就是要和getMacy方法里面new Macy()里的配置项对起来哦,这样就在这里面瀑布了(多余的解释,相信你肯定懂。那阵子~~)
<div className="macy-container 其他的样式名">
{
dataImages && dataImages.map((item,index)=>{
return (
<img src={item.url} alt="" className="img_item" key={index}/>
)
})
}
</div>
)
}
}
最最最最最最重要的问题
这个方法getMacy并不会跟着图片的增加而自动刷新,所以我们要手动刷新哦!
- 当你的页面下滑刷新(新增图片)的时候
- 当你的页面具有筛选功能的时候(图片改变)
- 当你的页面具有搜索功能的时候(图片改变)
- 等等等等
总而言之,只要你要展示的图片的数组(我这里是dataImages)的内容发生了改变(即setState了,又是多余的解释),我们就要回调一下getMacy这个方法哦,让他重新计算一下~~
this.setState({
dataImages:["啊,我变多了,少了~"]
},()=>{this.getMacy()})
OKK,一个简单的瀑布流ok了。 如果大佬们找到更好用的,更简单的,功能多的,样式好看的,麻烦也告诉俺一下,大家互相分享一下呀,感谢哦~❤️
哦对了,额外提一句,小程序上没法用这种库,就只能用文章开头的那种逻辑去搞了,是可以的~
啊啊啊,不对不对,当时光顾着实现效果了,没好好看人家文档,上文关于那个最最最最最最重要的那个问题,人家有自己的重新计算的方法:
- recalculate
- runOnImageLoad
那这样的话,我看看哈,上文代码let masonry = new Macy({....。。。。this.setState({ masonry })
那就是,new Macy的对象masonry放到state里了,那我们每次数据改变的时候,回调一下人家提供的重新计算的方法(this.state.masonry.recalculate()
),(之前是回调getMacy这个方法,哈哈,丢人丢人,垃圾代码出现了。)