前端实现一个上拉加载,下拉刷新,并且滑动一定的位置能够实现回到顶部的功能。这个在移动端上来说是一个很常见的功能。之前有看到有人用bette-scroll库来实现这个功能。
最基本的初始化代码如下:
import BScroll from 'better-scroll'
let wrapper = document.querySelector('.wrapper')
let scroll = new BScroll(wrapper)
查阅了better-scroll的api,发现它文档中提供了pullDownRefresh和pullUpLoad两个属性值。
(pullDownRefresh、pullUpLoad、click、probeType概念摘抄自官网:https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/#better-scroll 是什么)
pullDownRefresh
这个配置用于做下拉刷新功能,默认为 false。当设置为 true 或者是一个 Object 的时候,可以开启下拉刷新。
pullDownRefresh: {
threshold: 50,
stop: 20
}
可以配置顶部下拉的距离(threshold) 来决定刷新时机以及回弹停留的距离(stop)。当下拉刷新数据加载完毕后,需要执行 finishPullDown 方法。
pullUpLoad
这个配置用于做上拉加载功能,默认为 false。当设置为 true 或者是一个 Object 的时候,可以开启上拉加载。
pullUpLoad: {
threshold: 50
}
可以配置离(threshold)来决定开始加载的时机。当上拉加载数据加载完毕后,需要执行 finishPullUp 方法。
click
better-scroll 默认会阻止浏览器的原生 click 事件。当设置为 true,better-scroll 会派发一个 click 事件,我们会给派发的 event 参数加一个私有属性 _constructed,值为 true。
probeType
有时候我们需要知道滚动的位置。当 probeType 为 1 的时候,会非实时(屏幕滑动超过一定时间后)派发scroll 事件;当 probeType 为 2 的时候,会在屏幕滑动的过程中实时的派发 scroll 事件;当 probeType 为 3 的时候,不仅在屏幕滑动的过程中,而且在 momentum 滚动动画运行过程中实时派发 scroll 事件。如果没有设置该值,其默认值为 0,即不派发 scroll 事件。
对于pullDownRefresh、pullUpLoad,也参照了一些大牛的意见。这里面阈值的设置也要根据对于不同缩放程度的屏幕,乘以对应的缩放比。
export const getDeviceRatio () => {
var isAndroid = window.navigator.appVersion.match(/android/gi);
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = window.devicePixelRatio;
var dpr;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3) {
dpr = 3;
} else if (devicePixelRatio >= 2){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}
return dpr
}
scrollTo(x, y, time, easing)
参数:
{Number} x 横轴坐标(单位 px)
{Number} y 纵轴坐标(单位 px)
{Number} time 滚动动画执行的时长(单位 ms)
{Object} easing 缓动函数,一般不建议修改,如果想修改,参考源码中的 ease.js 里的写法
返回值:无
作用:滚动到指定的位置。
//父组件的方法
backTop() {
this.$refs.scroll.toTop()
},
//子组件的方法 (回到顶部)
toTop() {
this.scroll.scrollTo(0,0)
},
事件监听
pullingDown
触发时机:在一次下拉刷新的动作后,这个时机一般用来去后端请求数据。
this.scroll.on('pullingDown',()=>{
//do something
})
pullingUp
触发时机:在一次上拉加载的动作后,这个时机一般用来去后端请求数据。
this.scroll.on('pullingUp',()=>{
//do something
})
scroll
因为better-scroll 会默认阻止对原生scroll事件的监听,为实现滑动到一定位置后,显示回到顶部的悬浮窗。
this.scroll.on('scroll',(e)=>{
let status = this.scroll.y < -200
this.$emit('showIcon', status)
})
开发过程中,为了防止多次触发,需要加2个控制类的东西:(目的是为了保证每次只有一个事件在进行)
let onPullUp=true;
let onPullDown=true;
demo Code
<template>
<div>
<scroller v-if="dataList.length > 0"
id="scroll"
ref="scroll"
:top="top"
:stillHave="stillHave"
:dataList="dataList"
:refreshTime="refreshTime"
:pullDownRefresh="DOWN_CONFIG"
:pullUpLoad="UP_