React组件——下拉刷新、上拉加载

在移动端项目开发中,应用下拉刷新或上拉加载的场景非常多,避免编写重复代码,可以考虑把它封装成一个通用的组件,基于公司的技术栈,我们使用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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import React from 'react'
import _ from 'lodash'

class PullFresh extends React.Component {
constructor (props) {
super(props)
this.state = {
list: Array(50).fill(Math.ceil(Math.random() * 10))
}
this.dropPull = this.dropPull.bind(this)
}

dropPull () {
let loadingText = this.refs.dropPull
let _element = this.refs.refreshContainer
let startPos = 0
let transitionHeight = 0
let startFlag = false
let movingFlag = false

_element.addEventListener('touchstart', e => {
// console.log('初始位置:', e.touches[0].pageY)
if (this.getScrollTop() === 0) { // 只有当滚动条处于顶部时,才触发下拉刷新的的动作
startFlag = true
console.log('start')
startPos = e.touches[0].pageY
_element.style.position = 'relative'
_element.style.transition = 'transform 0s'
}
}, true)

_element.addEventListener('touchmove', e => {
console.log('moving')
// console.log('当前位置:', e.touches[0].pageY)
transitionHeight = e.touches[0].pageY - startPos // 获取下拉的距离
// console.log(transitionHeight)
if (transitionHeight > 0 && transitionHeight < 60) {
_element.style.transform = `translateY(${transitionHeight}px)`
movingFlag = true
}
if (transitionHeight > 55) {
loadingText.innerText = '释放更新'
}
}, true)

_element.addEventListener('touchend', e => {
console.log('end')
if (startFlag && movingFlag) { // 只有当在顶部下拉且移动了一段距离,才触发动作
_element.style.transition = 'transform 0.5s ease'
_element.style.transform = 'translateY(0px)'
loadingText.innerText = '更新中...'
console.log('获取上一页')
startFlag = false
movingFlag = false
}
// console.log(transitionHeight)

this.setState({
list: Array(50).fill(Math.ceil(Math.random() * 10))
})
}, true)
}

getScrollTop () {
let scrollTop = 0
if (document.documentElement && document.documentElement.scrollTop) {
scrollTop = document.documentElement.scrollTop
} else if (document.body) {
scrollTop = document.body.scrollTop
}
return scrollTop
}

getClientHeight () {
let clientHeight = 0
if (document.body.clientHeight && document.documentElement.clientHeight) {
clientHeight = Math.min(document.body.clientHeight, document.documentElement.clientHeight)
} else {
clientHeight = Math.max(document.body.clientHeight, document.documentElement.clientHeight)
}
return clientHeight
}

getScrollHeight () {
return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight)
}

upPull () {
let _text = this.refs.upPull
// let _container = this.refs.refreshContainer
window.addEventListener('scroll', () => {
// console.log(Math.ceil(this.getScrollTop()) + this.getClientHeight() === this.getScrollHeight())
if (Math.ceil(this.getScrollTop()) + this.getClientHeight() === this.getScrollHeight()) {
_text.innerText = '加载中...'
console.log('获取下一页数据')
const newList = this.state.list
newList.push(Math.ceil(Math.random() * 10), Math.ceil(Math.random() * 10), Math.ceil(Math.random() * 10))
setTimeout(() => {
this.setState({
list: newList
})
}, 1000)
}
}, true)
}
componentDidMount () {
this.dropPull()
this.upPull()
}

render () {
return (
<div>
<p ref='dropPull'>下拉刷新</p>
<ul ref='refreshContainer'>
{
_.map(this.state.list, (item, key) => {
return (
<li key={key}>{item}</li>
)
})
}
</ul>
<p ref='upPull'>上拉加载</p>
</div>
)
}
}

export default PullFresh