React单页面图片瀑布流——Macy.js

图片瀑布流

需求:一个数组里的图片按两列排列,图片尺寸不一样。
问题:如果只是简单的数组分成两个数组,有可能一组图片高度加起来远远高于另一组,视觉效果太差。

想了想简单的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

npm地址
GitHub地址

官方是这么说的:
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这个方法,哈哈,丢人丢人,垃圾代码出现了。)

emmm这些重新计算的方法,没有试,不过理论上是没有问题的!加油!!!❤️
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值