index.js
9.59 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
/**
* Created by gaoju on 2019/7/2.
* 滚动组件
* 注意:::此组件需要包裹在有高度的元素中,否则占满全屏
*/
import React, { Component } from 'react';
import IScroll from 'iscroll/build/iscroll-probe'
import styles from './index.css'
class Home extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
yesDown: false, // 是否已到了下拉刷新的高度
yesUp: false, // 是否已到了上拉加载的高度
loadingDownShow: false, // 是否处于刷新中状态
loadingUpShow: false, // 是否属于加载中状态
loadingDirection:'',//true 为下拉,false为上拉
loadingEnd:false,//
options: {
backgroundColor: '#f5f5f5', // 背景颜色
fontColor: '#888888', // 文字颜色
beyondHeight: 50, // 超过此长度后触发下拉或上拉,单位px
pulldownInfo: '下拉刷新',
pulldownReadyInfo: '松开刷新',
pulldowningInfo: '刷新中…',
pulldownEnd:"刷新完成",
pullupInfo: '上拉加载',
pullupReadyInfo: '松开加载',
pullupingInfo: '加载中…',
pullupEnd:"没有新的数据了…",
},
boxHeight: 0,
dataEnd:false,
backTopFlag:false,
};
this.myScroll = null;
this.timerRefresh = null; // 刷新iscroll的延时timer
this.iscrollTimer = null; // 检测高度变化的timer
this.elementToTarget = this.elementToTarget.bind(this);
}
componentDidMount() {
console.log('------componentDidMount-------------')
let options = {
mouseWheel: true, //鼠标事件
click: true,//点击事件
probeType: 3,
fadeScrollbars:false,
scrollbars: false,
//shrinkScrollbars: 'clip',//根据滚动缩放大小
//fadeScrollbars: true,//滚动条淡入淡出
//interactiveScrollbars:true,//滚动条能拖动
//bounce:true,//滚动边缘反弹
}
// this.myScroll = new IScroll('#wrapper',options);
let id = this.props.id + "_wrapper_scroller";
this.myScroll = new IScroll("#"+id, Object.assign({}, options, this.props.iscrollOptions));
this.myScroll.on('scroll', () => {
const myScroll = this.myScroll;
if (myScroll.y >0 && myScroll.y < this.state.options.beyondHeight) {
this.setState({
loadingDownShow: false,
loadingUpShow: false,
});
}else if (myScroll.y > this.state.options.beyondHeight) {
this.setState({
loadingDirection:'down',
loadingDownShow: true,
loadingUpShow: false,
});
}else if (myScroll.y < -(this.state.options.beyondHeight)) {
this.setState({
loadingDirection:'down',
});
}else if (myScroll.y < myScroll.maxScrollY - this.state.options.beyondHeight) {
this.setState({
loadingDirection:'up',
loadingDownShow: false,
loadingUpShow: true,
});
}
});
this.myScroll.on('scrollStart', () => {
window.top.addEventListener('mouseup', this.onMouseUpListener, false);
window.top.addEventListener('touchend', this.onMouseUpListener, false);
});
this.myScroll.on('scrollEnd', () => {
const myScroll = this.myScroll;
if (myScroll.y > -100) {
this.setState({
backTopFlag:false
});
}else if (myScroll.y < -100) {
this.setState({
backTopFlag:true
});
}
});
this.setState({
data: this.props.children,
options: Object.assign({}, this.state.options, this.props.options),
});
let scrollDom = document.getElementById(id);
scrollDom.addEventListener('touchmove', function (e) { e.preventDefault(); }, { passive: false });
//绑定父组件得方法
if(this.props.onRef){
this.props.onRef(this)
}
}
/** children内容改变时触发,表示已完成了刷新或加载 **/
static getDerivedStateFromProps(nextP, prevState) {
if (nextP.children != prevState.data) {
console.log('------getDerivedStateFromProps--------更新-----')
return {
data: nextP.children,
loadingDownShow: false,
loadingUpShow: false,
dataEnd: nextP.dataEnd ? true : false,
};
}
return null;
}
componentDidUpdate(prevP, prevS){
if(prevS.data !== this.state.data || prevP.hasDown !== this.props.hasDown || prevP.hasUp !== this.props.hasUp) {
console.log('------componentDidUpdate--------onRefresh-----')
// if(this.state.loadingDirection == 'down'){
// this.myScroll.scrollTo(0, this.myScroll.y);
// }
this.onRefresh();
}
}
/** 组件即将销毁时触发,销毁当前iscroll实例 **/
componentWillUnmount() {
console.log('------componentWillUnmount--------destroy-----')
//window.clearTimeout(this.iscrollTimer);
this.myScroll.destroy();
}
/** 刷新ISCROLL **/
onRefresh() {
const myScroll = this.myScroll;
window.clearTimeout(this.timerRefresh);
this.timerRefresh = window.setTimeout(() => {
myScroll.refresh();
}, 200);
}
//锚点跳转
elementToTarget(target){
this.myScroll.scrollToElement(document.querySelector("#"+target))
}
onMouseUpListener = () => {
const t = this;
let maxScrollY = t.myScroll.maxScrollY;
window.top.removeEventListener('mouseup', t.onMouseUpListener, false);
window.top.removeEventListener('touchend', t.onMouseUpListener, false);
// 如果滑动距离超过了设定界限并且当前没在下拉中,就触发下拉
if(t.myScroll.y >= t.state.options.beyondHeight) {
if(t.props.hasDown && t.props.onPullDownLoadMore) {
//t.myScroll.scrollTo(0, t.myScroll.y);
if (t.props.onPullDownLoadMore) {
this.props.onPullDownLoadMore();//加载新的数据
}
}
} else if (t.myScroll.y < t.myScroll.maxScrollY - t.state.options.beyondHeight) {
console.log('---onMouseUpListener------->>>>',t.myScroll.y,t.myScroll.maxScrollY,t.props.dataEnd,t.state.dataEnd)
if(t.props.hasUp && t.props.onPullUpLoadMore) {
if (t.props.onPullUpLoadMore) {
this.props.onPullUpLoadMore();//加载新的数据
}
}
}
};
render() {
let {data,backTopFlag} = this.state;
let id = this.props.id + "_wrapper_scroller";
return (
<div id={id} className={styles.wrapper_scroller} >
<div className={styles.scroller}>
<div className={styles.scroller_pullDown} style={{ display: !this.props.hasDown ? 'none' : 'inline-block' }}>
{
this.state.loadingDownShow ? (
<div className={styles.loadingSection}>
<img src={require('./assets/loading.gif')} />
<span className = {styles.msg} style={{ color: this.state.options.fontColor, display: 'inline-block' }}>
{this.state.options.pulldowningInfo}
</span>
</div>
) : (
<div>
<span className = {styles.msg} style={{ color: this.state.options.fontColor, display: 'inline-block' }}>
{this.state.options.pulldownInfo}
</span>
</div>
)
}
</div>
<div>
{this.props.children}
</div>
<div className={styles.scroller_pullUp} style={{ display: !this.props.hasUp ? 'none' : 'inline-block' }}>
{this.state.backTopFlag &&(
!this.state.dataEnd ? (
<div className={styles.loadingSection}>
<img src={require('./assets/loading.gif')} />
<span className = {styles.msg} style={{ color: this.state.options.fontColor, display: 'inline-block' }}>
{this.state.options.pullupingInfo}
</span>
</div>
) : (
<div className={styles.loadingSection}>
<span className = {styles.msg} style={{ color: this.state.options.fontColor, display: !this.props.hasUp ? 'none' : 'inline-block' }}>
{this.props.finishStr || this.state.options.pullupEnd}
</span>
</div>
)
)
}
</div>
</div>
{this.props.haveBackTop && (
<div style={{ display: backTopFlag ? 'block' : 'none'}} className={styles.backTopSection} onClick={()=>{this.myScroll.scrollTo(0,0,600)}}>
<img src={require("../../assets/image/backTop.png")} />
</div>
)}
</div>
);
}
}
export default Home;
/**
*
id: PropTypes.string, // id
children: PropTypes.object, // 数据
options: PropTypes.object, // 自定义参数
iscrollOptions: PropTypes.object, // iscroll原生参数
detectionHeight: PropTypes.bool, // 是否不停的检测高度变化
className: PropTypes.string, // 额外的class
onPullDownLoadMore: PropTypes.func, // 下拉刷新
onPullUpLoadMore: PropTypes.func, // 上拉加载更多
hasDown:PropTypes.bool,// 是否有下拉加载
hasUp:PropTypes.bool,// 是否有上拉加载更多
noDownStr:PropTypes.string,// 加载完提示
noUpStr:PropTypes.string,// 刷新完提示
finishStr:PropTypes.string,// 加载完成提示语
haveBackTop:PropTypes.bool,// 是否又返回顶部按钮
*
**/