iscroll 是一个 JS 滚动插件, 特性:高性能,资源占用少(4kb大小),无依赖,多平台
- 细粒度控制滚动位置,甚至在滚动过程中。你总是可以获取和设置滚动器的x,y坐标。
- 动画可以使用用户自定义的擦出功能(反弹'bounce',弹性'elastic',回退'back',...)。
- 你可以很容易的挂靠大量的自定义事件(onBeforeScrollStart, *
- 开箱即用的多平台支持。从很老的安卓设备到最新的iPhone,从Chrome浏览器到IE浏览器。
下拉刷新
iscroll 本身没有下拉刷新功能,但是可以自己实现
<template>
<div ref="scroll" class="wrap">
<div class="scroll-area">
<div :class="{hide: status===0}" class="refresh">{{ txt }}</div>
<div v-for="n in 50" class="item">{{ n }}</div>
</div>
</div>
</template>
export default {
data() {
scroll: null,
status: 0, // 用一个变量记录iscroll滚动状态,默认为0
txt: '下拉刷新', // 记录刷新文本,默认
},
watch: {
status() {
// 每次iscroll的状态码变化时,就要刷新iscroll,以便iscroll重新计算dom元素
this.iscroll.refresh();
}
},
mounted() {
this.scroll.on('scroll', e => {
const y = this.iscroll.y; // 监听下拉的y值,下拉是正值
if (y >= 50) { // 当下拉距离>=刷新文本高度时,
this.txt = '释放刷新';
this.status = 1; // 状态码变为1, 表示准备好刷新了
} else if (y > 0) { // 如果返回了,又不想刷新了,恢复status为0
this.txt = '下拉刷新';
this.status = 0;
}
})
this.scroll.on('scrollEnd', e => {
if (status === 1) { // 滚动停止时,如果是准备刷新状态
this.txt = '刷新中。。。';
this.status = 2; // 改变状态码,开始刷新
this.scroll.disable(); // 刷新过程禁止滚动,这个禁用方法视需求而定。
this.updateData(); // 假设有一个更新数据的method
}
})
},
methods: {
updateData() {
getData().then(_=>{
// 数据更新完成
this.txt = '刷新完成';
// 延迟1秒后继续隐藏刷新文本
setTimeout(_=>{
this.txt = '下拉刷新';
this.status = 0; // 状态重置为0
this.scroll.enable();
}, 1000);
})
}
}
<style>
.refresh{
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
&.hide{
/* 当status为0默认时,隐藏刷新文本,通过定位到容器外面 */
position: absolute;
left: 0;
top: -50px;
}
}
</style>
上拉加载
这个也是要自己实现,不过这个很简单了,判断滚动触底即可。
this.scroll.on('scroll', e => {
// 此处scrollEl是容器高度,contentEl是内容高度,因为y是负值,所以用scrollEl - contentEl
if (this.scroll.y <= scrollEl.offsetHeight - contentEl.offsetHeight) {
// do something 上拉加载
}
});
dom如下:
iscroll 参数配置可以参考 http://wiki.jikexueyuan.com/project/iscroll-5/
<template>
<div class="wrap">
<div class="scroll-area">
<div v-for="n in 1000" :key="n" class="item">{{ n }}</div>
</div>
</div>
</template>
<style>
.wrap{
width: 50px;
height: 50px;
overflow-x: hidden;
position: relative; // 因为iscroll的滚动条是定位实现,所以容器需要加一个相对定位
}
</script>
import IScroll from 'iscroll/build/iscroll-probe';
export default {
data: {
scroll: null
},
mounted() {
// 提示,因为transform是对dom操作,所以需要在这个生命周期操作
this.scroll = new IScroll('.wrap', {
mouseWheel: true, // 允许鼠标滚轮
preventDefault: true, // 当事件触发时是否执行preventDefault()默认值:true
scrollX: true, // 默认纵向滚动条scrollY:true
scrollY:false,
tap: 'myCustomTapEvent', // 通过传递一个字符串来自定义事件名称
// tap: true // 默认值:false,设置此属性为true,当滚动区域被点击或者触摸但并没有滚动时,可以让iScroll抛出一个自定义的tap事件
probeType: 3, // 滚动监听级别 有3档,3是像素级监听
scrollbars: true, // 开启滚动条
});
// 擦除动画的类型选项有:quadratic, circular, back, bounce, elastic。
// 反弹'bounce',弹性'elastic',回退'back'
this.scroll.scrollBy(0, -100,1000, IScroll.utils.ease.elastic) // 向下滚动100个像素
// 用iscroll实例注册scroll事件
this.scroll.on('scroll', e => {
// 此处不用箭头函数可以用this.x和this.y访问实时位置,用了箭头函数需要从实例上访问
console.log(this.scroll.x)
console.log(this.scroll.y)
})
}
}
1: iScroll刷新
由于滚动内容可能是异步获取并加载dom,要调用刷新方法
2: 监听位置
this.scroll = new IScroll('.wrap', {
probeType: 3, // 滚动监听级别 有3档,3是像素级监听
});
// 用iscroll实例注册scroll事件
this.scroll.on('scroll', e => {
// 此处不用箭头函数可以用this.x和this.y访问实时位置,用了箭头函数需要从实例上访问
// this.scroll.x
// this.scroll.y
})
复制代码
也可以使用prev
和next
方法跳上一个或者下一个
this.scroll.prev();
this.scroll.next();
3: 点击事件
<template>
<div ref="scroll" class="wrap">
<div class="scroll-area">
<div v-for="n in 50" class="item" @tap="onTap">{{ n }}</div>
</div>
</div>
</template>
this.scroll = new IScroll('.wrap', {
click: true, // 默认false,移动端使用自定义事件tap代替
tap: true, // 内置了tap事件,只要开启tap,就可以在元素上响应tap
});
总结
iscroll是个很灵活的库,可以根据自己想要的效果,自由配置。
如果对模块化比较熟悉,可以尝试将sticky
,下拉刷新
,上拉加载
封装到一个组件中
相关链接:https://blog.youkuaiyun.com/weixin_34102807/article/details/91467605