利用JavaScript实现一个下拉刷新组件

1LSGO软件技术团队

贡献人:LSGO船长

如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习。

If you like the content here, the greatest helpyou can give meis forwarding, so tell your friends and encourage them to learn together.

神马? 浏览器不都有自带的刷新按钮么?

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 ~

作者:elevenbeans

来源:elevenbeans.github.io/2017/09/19/pull-to-refresh/

经过8年多的发展,LSGO软件技术团队在地理信息系统、数据统计分析、计算机视觉领域积累了丰富的研发经验,也建立了人才培养的完备体系。

欢迎对算法设计与实现感兴趣的同学加入,与我们共同成长进步。

本微信公众平台长期系统化提供有关机器学习、软件研发、教育及学习方法、数学建模的知识,并将以上知识转化为实践。拒绝知识碎片化、耐心打磨技能、解决实际问题是我们的宗旨和追求。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180427B01C7200?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券