react 瀑布流和下拉加载以及图片加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import React from 'react'
import Masonry from 'masonry-layout' // 瀑布流
import InfiniteScroll from 'react-infinite-scroller' // 下拉加载
import imagesLoaded from 'imagesloaded' // 图片加载
import axios from 'axios'
import './style.less'

const arr = [
  'https://dss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3008142408,2229729459&fm=26&gp=0.jpg',
  'https://dss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3437217665,1564280326&fm=26&gp=0.jpg',
  'https://dss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2458227883,4095122505&fm=26&gp=0.jpg',
  'https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1761250919,1896060533&fm=26&gp=0.jpg',
  'https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2852083094,372235004&fm=26&gp=0.jpg',
  'https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2944705163,3932100810&fm=26&gp=0.jpg',
  'https://dss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3104686528,572431609&fm=26&gp=0.jpg',
]

// columnWidth: 200,
// itemSelector: '.grid-item' // 要布局的网格元素
// gutter: 10 // 网格间水平方向边距,垂直方向边距使用css的margin-bottom设置
// percentPosition: true // 使用columnWidth对应元素的百分比尺寸
// stamp:'.grid-stamp' // 网格中的固定元素,不会因重新布局改变位置,移动元素填充到固定元素下方
// fitWidth: true // 设置网格容器宽度等于网格宽度,这样配合css的auto margin实现居中显示
// originLeft: true // 默认true网格左对齐,设为false变为右对齐
// originTop: true // 默认true网格对齐顶部,设为false对齐底部
// containerStyle: { position: 'relative' } // 设置容器样式
// transitionDuration: '0.8s' // 改变位置或变为显示后,重布局变换的持续时间,时间格式为css的时间格式
// stagger: '0.03s' // 重布局时网格并不是一起变换的,排在后面的网格比前一个延迟开始,该项设置延迟时间  
// resize:  false // 改变窗口大小将不会影响布局
// initLayout: true // 初始化布局,设未true可手动初试化布局

export default class extends React.PureComponent {<!-- -->
  state = {<!-- -->
    hasMore: true, // 是否开启下拉加载
    data: arr, // 接受我每次的数据
    count: 0,
    width: '',
  }

  componentDidMount() {<!-- -->
    this.imagesOnload()
  }

  imagesOnload = () => {<!-- -->
    // 初始化你要监听哪个节点下的图片
    const elLoad = imagesLoaded('.content')
    // always 页面图片全部加载完 不管有没有加载失败的图片
    elLoad.on('always', (instance, image) => {<!-- -->
      // 图片加载后执行的方法
      // 拿第一次的数据
      this.advanceWidth() // 初始化瀑布流
    })
  }

  advanceWidth = () => {<!-- -->
    // new Masonry(节点, 配置)
    new Masonry(document.querySelector('.content'), {<!-- -->
      itemSelector: '.d', // 要布局的网格元素
      fitWidth: true, // 设置网格容器宽度等于网格宽度
      gutter: 20,
      columnWidth: '.d',
      originLeft: true,
    })
  }

  loadMoreData = page => {<!-- -->
    const {<!-- --> data, count } = this.state
    if (count && page > Math.ceil(count / 10)) return false
    axios.post('https://api.baxiaobu.com/index.php/home/v5/getuser', {<!-- --> data: {<!-- --> page, limit: 10 } })
      .then(res => {<!-- -->
        this.setState({<!-- -->
          data: [...data, ...data],
          count: res.count,
        })
        this.imagesOnload()
      })
      .catch(err => console.log(err))
  }

  render() {<!-- -->

    return (
      <div className="box">
        <InfiniteScroll
          initialLoad={<!-- -->false} // 不让它进入直接加载
          pageStart={<!-- -->1} // 设置初始化请求的页数
          loadMore={<!-- -->this.loadMoreData}  // 监听的ajax请求
          hasMore={<!-- -->true} // 是否继续监听滚动事件 true 监听 | false 不再监听
          useWindow={<!-- -->false} // 不监听 window 滚动条 如果你要监听 window 外层不能有任何节点
        >
          <div className="content">
            {<!-- -->
              this.state.data.map((value, key) => (
                <div key={<!-- -->key} className="d xxx">
                  <img src={<!-- -->value} />
                </div>
              ))
            }
          </div>
        </InfiniteScroll>
      </div>
    )
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
style.css 如下:

.box {<!-- -->
  box-sizing: border-box;
  margin: 0 auto;
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  box-sizing: border-box;
  border: 5px #0f0 solid;
  .content {<!-- -->
    width: 100%;
    margin: 0 auto;
    border: 5px #00F solid;
  }
  .xxx {<!-- -->
    width: 200px;
    margin: 0 0 20px 0;
    border: 5px #f00 solid;
    overflow: hidden;
  }
  .xxx img {<!-- -->
    width: 100%;

  }
}