作者:elevenbeans
elevenbeans.github.io/2017/09/19/pull-to-refresh/
神马? 浏览器不都有自带的刷新按钮么?
Web 页为什么要下(zi)拉(xing)刷(che)新 ?
这里特指移动端,原因如下:
精简成人话其实就是:被交互逼的
现有哪些轮子可以做到?
pulltorefresh.js:
目测这个是目前 Github 上最流行的 JS 下拉刷新组件了(15K stars)。highly customizable and dependency-free!
看使用方法,真的是简洁明了:
PullToRefresh.init({
mainElement:'body',// 想拖动(刷新)目标元素
onRefresh:function(){
window.location.reload();// 刷新动作完后的会执行的回调函数
}
});
不过这种单功能组件暴露了 20 个 API,着实有点多了。当然源码中有默认的一系列 default setting,个人觉得负担不大但不必要。
react-pull-to-refresh(https://github.com/bryaneaton13/react-pull-to-refresh)
看到一个 React 版本的就简直看到了亲人呐。虽然“只有” 200 stars,但是咱也不能完全以“星”取人啊,果断开始捣鼓。
onRefresh={this.handleRefresh}
className="your-own-class-if-you-want"
style={{
textAlign:'center'
Pulldowntorefresh
{items}
etc.
iscroll(https://github.com/cubiq/iscroll)
iScroll is a high performance, small footprint, dependency free, multi-platform javascript scroller. It works on desktop, mobile and smart TV.(并不是我喜欢复制粘贴凑篇幅,而是当我真正用过 TA 以后再回过头来再看这句话,就不厚道地笑了。平台通吃的东西在移动端性能真的可以很好么???)
不过,这是目前为止唯一一个让我成功完成任务的轮子。 然而还是放弃了,比较可惜,原因汇总如下:
我为什么不用上面的轮子?
对于一个 150 个元素的列表,左图为 iScroll 的 FPS;中间图为iScroll+lazyload 的 FPS;最右图为 native scroll +my pulltorefresh (下一段落详细说)的 FPS,看曲线,别看瞬时帧频,其实差距挺大但没有那么大。
所以,iscroll, 1 秒 3 帧。。。泪流满面,着实让我体会了一把页面卡成 PPT 的感觉。
对了,测试机器也提一句,是我的备用机。为了避免广告,我只能说是手机界说相声说的最好的那个胖子旗下的低端千元机。
不得已而为之,自造轮子
要把大象装冰箱,总共分几步?
第 1 步:监听原生 touchstart 事件,记录滑动起始位置ev.touches[0].pageY
第 2 步:监听原生 touchmove 事件,记录最新滑动位置与起始位置ev.touches[0].pageY的像素差 pullLength,如果大于 0 则为向下拖动,此时将pullLength结果同步设置成目标元素 translateY 值,实现元素跟随手势向下移动。当然,元素移动距离是要有上限的。
第 3 步:监听原生 touchend 事件,如果元素已在页面顶部,且下pullLength大于一个阈值(默认 60px),则触发 callback,并且将 translateY 的取值还原为 0,恢复目标元素位置 (有过渡效果是坠吼滴!)
这可能是史上最简陋的 JS 下拉刷新组件了吧 =,=
示例代码:
请注意:组件本身,不提供默认的 loading 提示元素!不提供默认的 loading 提示元素!不提供默认的 loading 提示元素! 需要自行设计样式并正确绑定,如下方代码中的 “ptr-instructions”。(提供了真的会有人不改直接用么???)
1
2
3
4
5
6
7
8
9
10
11
12
13
pullToRefresh.init({
// required
ptrElement: '#ptr-instructions', // 'pull to refresh' intructions element
ptrTextElement: '.ptr-instructions-text', // intructions' text element
targetElement: '#main', // target element that will be dragged and refreshed
// optional
instructionsPullToRefresh: 'pull to refresh', // text
instructionsReleaseToRefresh: 'Release to refresh', //text
instructionsRefreshing: 'refreshing', // text
threshold: 60, // minimum distance required to trigger the onPull callback
onPull: function(){ // callback fn
console.log('onPull fired');
}
});
Done ~
觉得本文对你有帮助?请分享给更多人
关注「前端大全」,提升前端技能
领取专属 10元无门槛券
私享最新 技术干货