better-scroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件。
better-scroll 只处理容器(wrapper)的第一个子元素(content)的滚动,其它的元素都会被忽略。
滚动原理
绿色部分为 wrapper,也就是父容器,它会有固定的高度。黄色部分为 content,它是父容器的第一个子元素,它的高度会随着内容的大小而撑高。那么,当 content 的高度不超过父容器的高度,是不能滚动的,而它一旦超过了父容器的高度,我们就可以滚动内容区了,这就是 better-scroll 的滚动原理。
安装better-scroll
npm install better-scroll --save
引入组件调用滚动效果
import BScroll from 'better-scroll'
mounted() {
// new BScroll(el, position)
new BScroll(document.querySelector('.content'),{
})
}
参数设置:
1. probeType
类型:Number
默认值:0
可选值:1、2、3
作用:有时候我们需要侦测滚动的位置。
this.bscoll = new BScroll(document.querySelector('.content'),{
// probeTybe 侦测类型
// 0和1 都不侦测
// 2 手指滚动过程中侦测,手指放开后的惯性不侦测
// 3 只要滚动都侦测
probeTybe: 3
})
this.bscoll.on('scroll', position => {
console.log(position);
})
2. 点击事件click
类型:Boolean
默认值:false
作用:better-scroll 默认会阻止浏览器的原生 click 事件。当设置为 true,better-scroll 会派发一个 click 事件,我们会给派发的 event 参数加一个私有属性 _constructed,值为 true。
this.bscoll = new BScroll(document.querySelector('.content'),{
probeTybe: 3,
click: true
})
3. pullUpLoad上拉加载事件
类型:Boolean | Object
默认值:false
作用:这个配置用于做上拉加载功能,默认为 false。当设置为 true 或者是一个 Object 的时候,可以开启上拉加载。
this.bscoll = new BScroll(this.$refs.content,{
// probeTybe: 3,
// click: true,
pullUpLoad: true
})
this.bscoll.on('pullingUp', () => {
// 代码块
this.bscoll.finishPullUp() //开启下拉加载完成,开启后才能再次调用下拉加载,默认只能加载一次
})
4. refresh 重新刷新可滚动高度
this.bscoll.refresh()
作用:重新计算 better-scroll,当 DOM 结构发生变化的时候务必要调用确保滚动的效果正常。
当图片在加载过程中滚动区域高度不断增加,图片加载过慢时会导致滚动到中途就无法滚动,此时应判断图片加载是否完成,完成后重新调用refresh刷新可滚动高度
图片加载监听
原生js:
img.onload = function() {
//
}
vue组件中监听 :绑定事件@load
<img src="~assets/img/common/top.png" @load="imgLoad" alt="">
5. 事件总线的使用 $bus, 用于监听事件
用于监听非父子组件的事件
- 在main.js中注册事件总线
//添加事件总线
Vue.prototype.$bus = new Vue()
new Vue({
router,
render: h => h(App)
}).$mount('#app')
- $emit()发射事件
imgLoad() {
//事件总线发射事件
this.$bus.$emit('itemImgLoad')
}
- $on()获取事件监听,在mounted()钩子函数中接收,在组件被挂载时接收监听事件
mounted() {
//图片加载事件接收
this.$bus.$on('itemImgLoad', () => {
this.$refs.scroll.refresh()
})
},
refresh() {
this.scroll.refresh()
}
6. 针对refresh()刷新频繁问题解决, 进行防抖操作
防抖 debounce /节流throttle
apply() 改变this指向
var person = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person1 = {
firstName: "Bill",
lastName: "Gates",
}
person.fullName.apply(person1); // 将返回 "Bill Gates"
封装debounce方法
debounce(func, delay){
}
参数:
func: 把一个函数作为参数传进去
delay: 延迟时间
methods: {
//防抖
debounce(func, delay = 50) {
let timer = null;
return function(...args) { //返回一个函数
if(timer) timer = clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args) //执行func函数
},delay)
}
}
}
图片加载完成后事件调用
mounted() {
//图片加载事件接收
let refresh = this.debounce(this.$refs.scroll.refresh, 50)//相当于debounce的返回值
this.$bus.$on('itemImgLoad', () => {
refresh();
})
},
检测refresh被调用次数
refresh() {
console.log('refresh次数检测');
this.scroll && this.scroll.refresh()
}