IntersectionObserver实现react列表滚动

前言

想法是在列表下方或上方添加一个div元素,当元素出现在浏览器视口,滚动列表。

用法
初始化
1
2
3
4
5
6
7
8
constructor(props) {
super(props);
this.ioNext = null;
this.nextContainer = null;
this.ioPrev = null;
this.prevContainer = null;
this.loadNextMore = this.loadNextMore.bind(this);
this.loadPrevMore = this.loadPrevMore.bind(this);
  • ioNext是下拉IntersectionObserver对象,ioPrev对应上拉
  • nextContainer是需要观察下拉时出现在浏览器视口的元素,prevContainer同理
创建元素
1
2
let loadNextMore = <div ref={div => {this.nextContainer=div;}}><Spin tip="loading..." className={styles['loading-tips']}  /></div>; 
let loadPrevMore = <div ref={div => {this.prevContainer=div;}}><Spin tip="loading..." className={styles['loading-tips']} /></div>;

将loadNextMore、loadPrevMore放在render中return就好,具体用法根据实际情况

监听元素行为
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
componentDidUpdate() {
if(this.nextContainer) {
this.ioNext = new IntersectionObserver(entry => {
if(window.innerHeight > entry[0].boundingClientRect.top) {
this.loadNextMore();
}
}, {});
this.ioNext.observe(this.nextContainer);
}
if (this.prevContainer) {
this.ioPrev = new IntersectionObserver(entry => {
if(entry[0].boundingClientRect.top > 0 && entry[0].boundingClientRect.top < window.innerHeight) {
this.loadPrevMore();
}
}, {});
this.ioPrev.observe(this.prevContainer);
}
}


loadPrevMore() {
//具体实现
}

loadNextMore() {
//具体实现
}
注意

上拉加载的情况,若直接替换state中渲染元素需考虑将上拉加载出来的数据向上偏移一定值。