better-scroll 2.X手册

3 篇文章 0 订阅
1 篇文章 0 订阅

使用

基础滚动

如果你只需要一个拥有基础滚动能力的列表,只需要引入 core。

import BScroll from '@better-scroll/core'
let bs = new BScroll('.wrapper', {
  // ...... 详见配置项
})

增强型滚动

如果你需要一些额外的 feature。比如 pull-up,你需要引入额外的插件,详情查看插件

import BScroll from '@better-scroll/core'
import Pullup from '@better-scroll/pull-up'

// 注册插件
BScroll.use(Pullup)

let bs = new BScroll('.wrapper', {
  probeType: 3,
  pullUpLoad: true
})

全能力的滚动

如果你觉得一个个引入插件很费事,我们提供了一个拥有全部插件能力的 BetterScroll 包。它的使用方式与 1.0 版本一模一样,但是体积会相对大很多,推荐按需引入

import BScroll from 'better-scroll'

let bs = new BScroll('.wrapper', {
  // ...
  pullUpLoad: true,
  wheel: true,
  scrollbar: true,
  // and so on
})

配置项

BetterScroll 支持很多参数配置,可以在初始化的时候传入第二个参数,比如:

import BScroll from '@better-scroll/core'
let scroll = new BScroll('.wrapper',{
    scrollY: true,
    click: true
})

这样就实现了一个具有纵向可点击的滚动效果的列表。BetterScroll 支持的参数非常多,接下来我们来列举 BetterScroll 支持的参数。

startX

  • 类型number
  • 默认值0
  • 作用:横轴方向初始化位置。

startY

  • 类型number
  • 默认值0
  • 作用:纵轴方向初始化位置。

scrollX

  • 类型boolean
  • 默认值false
  • 作用:当设置为 true 的时候,可以开启横向滚动。
  • 备注:当设置 eventPassthrough 为 ‘horizontal’ 的时候,该配置无效。

scrollY

  • 类型boolean
  • 默认值true
  • 作用:当设置为 true 的时候,可以开启纵向滚动。
  • 备注:当设置 eventPassthrough 为 ‘vertical’ 的时候,该配置无效。

freeScroll

  • 类型boolean
  • 默认值false
  • 作用:在默认情况下,由于人的手指无法做到绝对垂直或者水平的运动,因此在一次手指操作的过程中,都会存在横向以及纵向的偏移量,内部默认会摒弃偏移量较小的一个方向,保留另一个方向的滚动。但是在某些场景我们需要同时计算横向以及纵向的手指偏移距离,而不是只计算偏移量较大的一个方向,这个时候我们只要设置 freeScroll 为 true 即可。
  • 备注:当设置 eventPassthrough 不为空的时候,该配置无效。
  • 示例
// 手指起点的坐标 e1: { pageX: 120, pageY: 120 }
// 手指终点的坐标 e2: { pageX: 121, pageY: 140 }
// offsetX:  e2.pageX - e1.pageX = 1
// offsetY:  e2.pageY - e1.pageY = 20
// 如果 freeScroll 为 false, 由于 offsetY > offsetX + directionLockThreshold
// offsetX 被重置为 0, 只保留 offsetY 的偏移量,因此只做一次纵向滚动

directionLockThreshold

  • 类型number
  • 默认值5
  • 作用:当 freeScroll 为 false 的情况,我们需要锁定只滚动一个方向的时候,我们在初始滚动的时候根据横轴和纵轴滚动的绝对值做差,当差值大于 directionLockThreshold 的时候来决定滚动锁定的方向。
  • 备注:当设置 eventPassthrough 的时候,directionLockThreshold 设置无效,始终为 0。

eventPassthrough

  • 类型string
  • 默认值''
  • 可选值'vertical' | 'horizontal'
  • 作用:有时候我们使用 BetterScroll 在某个方向模拟滚动的时候,希望在另一个方向保留原生的滚动(比如轮播图,我们希望横向模拟横向滚动,而纵向的滚动还是保留原生滚动,我们可以设置 eventPassthrough 为 vertical;相应的,如果我们希望保留横向的原生滚动,可以设置eventPassthrough为 horizontal)。
  • 备注eventPassthrough 的设置会导致其它一些选项配置无效,需要小心使用它。

click

  • 类型boolean
  • 默认值false
  • 作用:BetterScroll 默认会阻止浏览器的原生 click 事件。当设置为 true,BetterScroll 会派发一个 click 事件,我们会给派发的 event 参数加一个私有属性 _constructed,值为 true。

dblclick

  • 类型boolean | Object
  • 默认值false
  • 作用:派发双击点击事件。当配置成 true 的时候,默认 2 次点击的延时为 300 ms,如果配置成对象可以修改 delay
  dblclick: {
    delay: 300
  }

tap

  • 类型string
  • 默认值''
  • 作用:因为 BetterScroll 会阻止原生的 click 事件,我们可以设置 tap 为 ‘tap’,它会在区域被点击的时候派发一个 tap 事件,你可以像监听原生事件那样去监听它。

bounce

  • 类型boolean | Object
  • 默认值true
  • 作用:当滚动超过边缘的时候会有一小段回弹动画。设置为 true 则开启动画。
  bounce: {
    top: true,
    bottom: true,
    left: true,
    right: true
  }

bounce 可以支持关闭某些边的回弹效果,可以设置对应边的 keyfalse 即可。

TIP

如果想要便捷的设置所有边为 true 或者 false,只需要设置 bounce 为 true 或 false 即可。

bounceTime

  • 类型number
  • 默认值800(单位ms)
  • 作用:设置回弹动画的动画时长。

momentum

  • 类型boolean
  • 默认值true
  • 作用:当快速在屏幕上滑动一段距离的时候,会根据滑动的距离和时间计算出动量,并生成滚动动画。设置为 true 则开启动画。

momentumLimitTime

  • 类型number
  • 默认值300(单位ms)
  • 作用:只有在屏幕上快速滑动的时间小于 momentumLimitTime,才能开启 momentum 动画。

momentumLimitDistance

  • 类型number
  • 默认值15(单位px)
  • 作用:只有在屏幕上快速滑动的距离大于 momentumLimitDistance,才能开启 momentum 动画。

swipeTime

  • 类型number
  • 默认值2500(单位ms)
  • 作用:设置 momentum 动画的动画时长。

swipeBounceTime

  • 类型number
  • 默认值500(单位ms)
  • 作用:设置当运行 momentum 动画时,超过边缘后的回弹整个动画时间。

deceleration

  • 类型number
  • 默认值0.0015
  • 作用:表示 momentum 动画的减速度。

flickLimitTime

  • 类型number
  • 默认值200(单位ms)
  • 作用:有的时候我们要捕获用户的轻拂动作(短时间滑动一个较短的距离)。只有用户在屏幕上滑动的时间小于 flickLimitTime ,才算一次轻拂。

flickLimitDistance

  • 类型number
  • 默认值100(单位px)
  • 作用:只有用户在屏幕上滑动的距离小于 flickLimitDistance ,才算一次轻拂。

resizePolling

  • 类型number
  • 默认值60(单位ms)
  • 作用:当窗口的尺寸改变的时候,需要对 BetterScroll 做重新计算,为了优化性能,我们对重新计算做了延时。60ms 是一个比较合理的值。

probeType

  • 类型number
  • 默认值0
  • 可选值1|2|3
  • 作用:决定是否派发 scroll 事件,对页面的性能有影响,尤其是在 useTransition 为 true 的模式下。
// 派发 scroll 的场景分为两种:
// 1. 手指作用在滚动区域(content DOM)上;
// 2. 调用 scrollTo 方法或者触发 momentum 滚动动画(其实底层还是调用 scrollTo 方法)

// 对于 v2.1.0 版本,对 probeType 做了一次统一

// 1. probeType 为 0,在任何时候都不派发 scroll 事件,
// 2. probeType 为 1,仅仅当手指按在滚动区域上,每隔 momentumLimitTime 毫秒派发一次 scroll 事件,
// 3. probeType 为 2,仅仅当手指按在滚动区域上,一直派发 scroll 事件,
// 4. probeType 为 3,任何时候都派发 scroll 事件,包括调用 scrollTo 或者触发 momentum 滚动动画

preventDefault

  • 类型boolean
  • 默认值true
  • 作用:当事件派发后是否阻止浏览器默认行为。这个值应该设为 true,除非你真的知道你在做什么,通常你可能用到的是 preventDefaultException

preventDefaultException

  • 类型Object
  • 默认值{ tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|AUDIO)$/}
  • 作用:BetterScroll 会阻止原生的滚动,这样也同时阻止了一些原生组件的默认行为。这个时候我们不能对这些元素做 preventDefault,所以我们可以配置 preventDefaultException。默认值 {tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|AUDIO)$/}表示标签名为 input、textarea、button、select、audio 这些元素的默认行为都不会被阻止。
  • 备注:这是一个非常有用的配置,它的 key 是 DOM 元素的属性值,value 可以是一个正则表达式。比如我们想配一个 class 名称为 test 的元素,那么配置规则为 {className:/(^|\s)test(\s|$)/}

tagException

  • 类型Object
  • 默认值{ tagName: /^TEXTAREA$/ }
  • 作用:如果 BetterScroll 嵌套了 textarea 等表单元素,往往用户的预期应该是滑动 textarea 不应该引起 bs 滚动,也就是如果操纵的 DOM(eg:textarea 标签) 命中了配置的规则,bs 不会滚动。
  • 备注:这是一个非常有用的配置,它的 key 是 DOM 元素的属性值,value 可以是一个正则表达式。比如我们想配一个 classname 含有 test 类名的元素,那么配置规则为 {className:/(^|\s)test(\s|$)/}

HWCompositing

  • 类型boolean
  • 默认值true
  • 作用:是否开启硬件加速,开启它会在 content 元素上添加 translateZ(1px) 来开启硬件加速从而提升动画性能,有很好的滚动效果。
  • 备注:只有支持硬件加速的浏览器开启才有效果。

useTransition

  • 类型boolean
  • 默认值true
  • 作用:是否使用 CSS3 transition 动画。如果设置为 false,则使用 requestAnimationFrame 做动画。

bindToWrapper

  • 类型boolean
  • 默认值false
  • 作用:touchmove 事件通常会绑定到 document 上而不是滚动的容器(wrapper)上,当移动的过程中光标(通常对于 PC 场景)离开滚动的容器滚动仍然会继续,这通常是期望的。当然你也可以把 move 事件绑定到滚动的容器上,bindToWrapper 设置为 true 即可,这样一旦移动的过程中光标离开滚动的容器,滚动会立刻停止。
  • 注意:对于移动端来说,就算 touchmove 事件绑定在 wrapper 上,手指离开 wrapper,依然能移动 wrapper。

disableMouse

  • 类型boolean
  • 默认值:根据当前浏览器环境计算而来
  • 作用:当在移动端环境(支持 touch 事件),disableMouse 会计算为 true,这样就不会监听鼠标相关的事件,而在 PC 环境,disableMouse 会计算为 false,就会监听鼠标相关事件。

disableTouch

  • 类型boolean
  • 默认值:根据当前浏览器环境计算而来
  • 作用:当在移动端环境(支持 touch 事件),disableTouch 会计算为 false,监听 touch 相关的事件,而在 PC 环境,disableTouch 会计算为 true,不会监听 touch 相关事件。

WARNING

考虑到用户的一些特定场景,比如在平板电脑需要支持 touch 事件,平板电脑接入鼠标又得支持 mouse 事件,那么实例化 BetterScroll 需要如下配置:

let bs = new BScroll('.wrapper', {
  disableMouse: false,
  disableTouch: false
})

由于不同设备、不同浏览器环境的底层实现逻辑不同,BetterScroll 内部计算是否监听 touch 还是 mouse 事件可能会有判断失误,因此你可以根据以上的选项配置来解决这类问题。

autoBlur

  • 类型boolean
  • 默认值true
  • 作用:在滚动之前会让当前激活的元素(input、textarea)自动失去焦点。

stopPropagation

  • 类型boolean
  • 默认值false
  • 作用:是否阻止事件冒泡。多用在嵌套 scroll 的场景。

bindToTarget

  • 类型boolean
  • 默认值false
  • 作用:将 touch 或者 mouse 事件绑定在 content 元素而不是容器 wrapper上,多用于 movable 场景

autoEndDistance

  • 类型number
  • 默认值5
  • 作用:当手指操作幅度过大,滑出视口导致可能没有触发 touchend 事件,因此 autoEndDistance 的作用就是当手指即将脱离当前视口的时候,自动调用 touchend 事件。默认距离边界 5px 的时候,结束滚动。

outOfBoundaryDampingFactor

  • 类型number
  • 默认值1 / 3
  • 作用:当超过边界的时候,进行阻尼行为,阻尼因子越小,阻力越大,取值范围:[0, 1]。

specifiedIndexAsContent 2.0.4

  • 类型number
  • 默认值0
  • 作用:指定 wrapper 对应索引的子元素作为 content,默认情况下 BetterScroll 采用的是 wrapper 的第一个子元素作为 content。
<div class="wrapper">
   <div class="content1">
      <div class="conten1-item">1.1</div>
      <div class="conten1-item">1.2</div>
   </div>
   <div class="content2">
      <div class="conten2-item">2.1</div>
      <div class="conten2-item">2.2</div>
   </div>
</div>
// 针对以上 DOM 结构,在 BetterScroll 版本 <= 2.0.3,内部只会使用 wrapper.children[0],也就是 div.content1 作为 content
// 当 版本 >= 2.0.4 的时候,可以通过 specifiedIndexAsContent 配置项来指定 content

let bs = new BScroll('.wrapper', {
   specifiedIndexAsContent: 1 // 使用 div.content2 作为 BetterScroll 的 content
})

API

如果想要彻底了解 BetterScroll,就需要了解其实例的常用属性、灵活的方法以及提供的事件与钩子。

属性

有时候我们想基于 BetterScroll 做一些扩展,需要对 BetterScroll 的一些属性有所了解,下面介绍几个常用属性。

x

  • 类型:number
  • 作用:bs 横轴坐标。

y

  • 类型:number
  • 作用:bs 纵轴坐标。

maxScrollX

  • 类型:number
  • 作用:bs 最大横向滚动位置。
  • 备注:bs 横向滚动的位置区间是 [minScrollX, maxScrollX],并且 maxScrollX 是负值。

#minScrollX

  • 类型:number
  • 作用:bs 最小横向滚动位置。
  • 备注:bs 横向滚动的位置区间是 [minScrollX, maxScrollX],并且 minScrollX 是正值。

maxScrollY

  • 类型:number
  • 作用:bs 最大纵向滚动位置。
  • 备注:bs 纵向滚动的位置区间是 [minScrollY, maxScrollY],并且 maxScrollY 是负值。

minScrollY

  • 类型:number
  • 作用:bs 最小纵向滚动位置。
  • 备注:bs 纵向滚动的位置区间是 [minScrollY, maxScrollY],并且 minScrollY 是正值。

movingDirectionX

  • 类型:number
  • 作用:判断 bs 滑动过程中的方向(左右)。
  • 备注:-1 表示手指从左向右滑,1 表示从右向左滑,0 表示没有滑动。

movingDirectionY

  • 类型:number
  • 作用:判断 bs 滑动过程中的方向(上下)。
  • 备注:-1 表示手指从上往下滑,1 表示从下往上滑,0 表示没有滑动。

directionX

  • 类型:number
  • 作用:判断 bs 滑动结束后相对于开始滑动位置的方向(左右)。
  • 备注:-1 表示手指从左向右滑,1 表示从右向左滑,0 表示没有滑动。

directionY

  • 类型:number
  • 作用:判断 bs 滑动结束后相对于开始滑动位置的方向(上下)。
  • 备注:-1 表示手指从上往下滑,1 表示从下往上滑,0 表示没有滑动。

enabled

  • 类型:boolean,
  • 作用:判断当前 bs 是否处于启用状态,不再响应手指的操作。

pending

  • 类型:boolean,
  • 作用:判断当前 bs 是否处于滚动动画过程中。

方法

BetterScroll 提供了很多灵活的 API,当我们基于 BetterScroll 去实现一些 feature 的时候,会用到这些 API,了解它们会有助于开发更加复杂的需求。

refresh()

  • 参数:无
  • 返回值:无
  • 作用:重新计算 BetterScroll,当 DOM 结构发生变化的时候务必要调用确保滚动的效果正常。

scrollTo(x, y, time, easing, extraTransform)

  • 参数

    • {number} x 横轴坐标(单位 px)
    • {number} y 纵轴坐标(单位 px)
    • {number} time 滚动动画执行的时长(单位 ms)
    • {Object} easing 缓动函数,一般不建议修改,如果想修改,参考源码中的 packages/shared-utils/src/ease.ts 里的写法
    • {Object} extraTransform,只有在你想要修改 CSS transform 的一些其他属性的时候,你才需要传入此参数,结构如下:
    let extraTransform = {
      // 起点的属性
      start: {
        scale: 0
      },
      // 终点的属性
      end: {
        scale: 1.1
      }
    }
    bs.scrollTo(0, -60, 300, undefined, extraTransform)
    
  • 返回值:无

  • 作用:相对于当前位置偏移滚动 x,y 的距离。

scrollBy(x, y, time, easing)

  • 参数

    • {number} x 横轴变化量(单位 px)
    • {number} y 纵轴变化量(单位 px)
    • {number} time 滚动动画执行的时长(单位 ms)
    • {Object} easing 缓动函数,一般不建议修改,如果想修改,参考源码中的 packages/shared-utils/src/ease.ts 里的写法
  • 返回值:无

  • 作用:相对于当前位置偏移滚动 x,y 的距离。

scrollToElement(el, time, offsetX, offsetY, easing)

  • 参数

    • {DOM | string} el 滚动到的目标元素, 如果是字符串,则内部会尝试调用 querySelector 转换成 DOM 对象。
    • {number} time 滚动动画执行的时长(单位 ms)
    • {number | boolean} offsetX 相对于目标元素的横轴偏移量,如果设置为 true,则滚到目标元素的中心位置
    • {number | boolean} offsetY 相对于目标元素的纵轴偏移量,如果设置为 true,则滚到目标元素的中心位置
    • {Object} easing 缓动函数,一般不建议修改,如果想修改,参考源码中的 packages/shared-utils/src/ease.ts 里的写法
  • 返回值:无

  • 作用:滚动到指定的目标元素。

stop()

  • 参数:无
  • 返回值:无
  • 作用:立即停止当前运行的滚动动画。

enable()

  • 参数:无
  • 返回值:无
  • 作用:启用 BetterScroll, 默认 开启。

disable()

  • 参数:无
  • 返回值:无
  • 作用:禁用 BetterScroll,DOM 事件(如 touchstart、touchmove、touchend)的回调函数不再响应。

destroy()

  • 参数:无
  • 返回值:无
  • 作用:销毁 BetterScroll,解绑事件。

on(type, fn, context)

  • 参数

    • {string} type 事件名
    • {Function} fn 回调函数
    • {Object} context 函数执行的上下文环境,默认是 this
  • 返回值:无

  • 作用:监听当前实例上的钩子函数。如:scroll、scrollEnd 等。

  • 示例

import BScroll from '@better-scroll/core'
let scroll = new BScroll('.wrapper', {
  probeType: 3
})
function onScroll(pos) {
    console.log(`Now position is x: ${pos.x}, y: ${pos.y}`)
}
scroll.on('scroll', onScroll)

once(type, fn, context)

  • 参数

    • {string} type 事件名
    • {Function} fn 回调函数
    • {Object} context 函数执行的上下文环境,默认是 this
  • 返回值:无

  • 作用:监听一个自定义事件,但是只触发一次,在第一次触发之后移除监听器。

off(type, fn)

  • 参数

    • {string} type 事件名
    • {Function} fn 回调函数
  • 返回值:无

  • 作用:移除自定义事件监听器。只会移除这个回调的监听器。

  • 示例

import BScroll from '@better-scroll/core'
let scroll = new BScroll('.wrapper', {
  probeType: 3
})
function handler() {
    console.log('bs is scrolling now')
}
scroll.on('scroll', handler)

scroll.off('scroll', handler)

事件 VS 钩子

基于 2.x 的架构设计,以及对 1.x 事件的兼容,我们延伸出两个概念 ——『事件』以及『钩子』。从本源上来说它们都是属于 EventEmitter 实例,只是叫法不一样。下面我们从节选的源码来讲解一下:

  export default BScrollCore extends EventEmitter {
    hooks: EventEmitter
  }
  • BScrollCore

    本身继承了 EventEmitter。它派发出来的,我们都称之为『事件』。

      import BScroll from '@better-scroll/core'
      let bs = new BScroll('.wrapper', {})
    
      // 监听 bs 的 scroll 事件
      bs.on('scroll', () => {})
      // 监听 bs 的 refresh 事件
      bs.on('refresh', () => {})
    
  • BScrollCore.hooks

    hooks 也是 EventEmitter 的实例。它派发出来的,我们都称之为『钩子』。

      import BScroll from '@better-scroll/core'
      let bs = new BScroll('.wrapper', {})
    
      // 监听 bs 的 refresh 钩子
      bs.hooks.on('refresh', () => {})
      // 监听 bs 的 enable 钩子
      bs.hooks.on('enable', () => {})
    

相信现在大家对两者有了更好的区分吧,『事件』是为了 1.x 的兼容考虑,用户一般关注的是事件的派发,但是如果要编写一款插件,你应该更加关注『钩子』。

事件

在 2.0 当中,BetterScroll 事件与 1.x 的事件是拉齐的,只有 BetterScroll 会派发『事件』,如果你在编写插件的时候需要暴露事件,你也应该通过 BetterScroll 来派发,详细的教程看这,目前的事件分为下面几种:

  • refresh

    • 触发时机:BetterScroll 重新计算
      import BetterScroll from '@better-scroll/core'
    
      const bs = new BetterScroll('.wrapper', {})
    
      bs.on('refresh', () => {})
    
  • enable

    • 触发时机:BetterScroll 启用,开始响应用户交互
      bs.on('enable', () => {})
    
  • disable

    • 触发时机:BetterScroll 禁用,不再响应用户交互
      bs.on('disable', () => {})
    
  • beforeScrollStart

    • 触发时机:用户手指放在滚动区域的时候
      bs.on('beforeScrollStart', () => {})
    
  • scrollStart

    • 触发时机:content 元素满足滚动条件,即将开始滚动
      bs.on('scrollStart', () => {})
    
  • scroll

    • 触发时机:正在滚动
      bs.on('scroll', (position) => {
        console.log(position.x, position.y)
      })
    
  • scrollEnd

    • 触发时机:滚动结束,或者让一个正在滚动的 content 强制停止
      bs.on('scrollEnd', () => {})
    
  • scrollCancel

    • 触发时机:滚动取消
      bs.on('scrollCancel', () => {})
    
  • touchEnd

    • 触发时机:用户手指离开滚动区域
      bs.on('touchEnd', () => {})
    
  • flick

    • 触发时机:用户触发轻拂操作
      bs.on('flick', () => {})
    
  • destroy

    • 触发时机:BetterScroll 销毁
      bs.on('destroy', () => {})
    
  • contentChanged 2.0.4

    • 触发时机:在调用 bs.refresh(),探测到 content DOM 变成了其他元素的时候
      // bs 版本 >= 2.0.4
      bs.on('contentChanged', (newContent: HTMLElement) => {})
    

以下的事件必须注册括号中的插件才会派发:

  • alterOptions(*mouse-wheel*)

    • 触发时机:滚轮滚动开始
      import BetterScroll from '@better-scroll/core'
      import MouseWheel from '@better-scroll/mouse-wheel'
    
      BetterScroll.use(MouseWheel)
      const bs = new BetterScroll('.wrapper', {
        mouseWheel: true
      })
    
      bs.on('alterOptions', (mouseWheelOptions) => {
        /**
         * mouseWheelOptions.speed:鼠标滚轮滚动的速度
         * mouseWheelOptions.invert:滚轮滚动和 BetterScroll 滚动的方向是否一致
         * mouseWheelOptions.easeTime:滚动动画的缓动时长。
         * mouseWheelOptions.discreteTime:触发 wheelEnd 的间隔时长
         * mouseWheelOptions.throttleTime:滚轮滚动是高频率的动作,因此可以通过 throttleTime 来限制触发频率
         * mouseWheelOptions.dampingFactor:阻尼因子,当超出边界会施加阻力
         **/
      })
    
  • mousewheelStart(*mouse-wheel*)

    • 触发时机:滚轮滚动开始
      import BetterScroll from '@better-scroll/core'
      import MouseWheel from '@better-scroll/mouse-wheel'
    
      BetterScroll.use(MouseWheel)
      const bs = new BetterScroll('.wrapper', {
        mouseWheel: true
      })
    
      bs.on('mousewheelStart', () => {})
    
  • mousewheelMove(*mouse-wheel*)

    • 触发时机:滚轮滚动中
      bs.on('mousewheelMove', () => {})
    
  • mousewheelEnd(*mouse-wheel*)

    • 触发时机:滚轮滚动结束
      bs.on('mousewheelEnd', () => {})
    
  • pullingDown(*pull-down*)

    • 触发时机:当顶部下拉距离超过阈值
      import BetterScroll from '@better-scroll/core'
      import Pulldown from '@better-scroll/pull-down'
    
      BetterScroll.use(Pulldown)
      const bs = new BetterScroll('.wrapper', {
        pullDownRefresh: true
      })
    
      bs.on('pullingDown', () => {
        await fetchData()
        bs.finishPullDown()
      })
    
  • pullingUp(*pull-up*)

    • 触发时机:当底部下拉距离超过阈值
      import BetterScroll from '@better-scroll/core'
      import Pullup from '@better-scroll/pull-up'
    
      BetterScroll.use(Pullup)
      const bs = new BetterScroll('.wrapper', {
        pullUpLoad: true
      })
    
      bs.on('pullingUp', () => {
        await fetchData()
        bs.finishPullUp()
      })
    
  • slideWillChange(*slide*)

    • 触发时机:轮播图即将要切换 Page
      import BetterScroll from '@better-scroll/core'
      import Slide from '@better-scroll/slide'
    
      BetterScroll.use(Slide)
    
      const bs = new BetterScroll('.wrapper', {
        slide: true,
        momentum: false,
        bounce: false,
        probeType: 2
      })
    
      bs.on('slideWillChange', (page) => {
        // 即将要切换的页面
        console.log(page.pageX, page.pageY)
      })
    
  • beforeZoomStart(*zoom*)

    • 触发时机:双指接触缩放元素时
      import BetterScroll from '@better-scroll/core'
      import Zoom from '@better-scroll/zoom'
    
      BetterScroll.use(Zoom)
    
      const bs = new BetterScroll('.wrapper', {
        zoom: true
      })
    
      bs.on('beforeZoomStart', () => {})
    
  • zoomStart(*zoom*)

    • 触发时机:双指缩放距离超过最小阈值
      bs.on('zoomStart', () => {})
    
  • zooming(*zoom*)

    • 触发时机:双指缩放行为正在进行时
      bs.on('zooming', ({ scale }) => {
        // scale 当前 scale
      })
    
  • zoomEnd(*zoom*)

    • 触发时机:双指缩放行为结束后
      bs.on('zoomEnd', ({ scale }) => {})
    

#钩子

钩子是 2.0 版本延伸出来的概念,它的本质与事件相同,都是 EventEmitter 实例,也就是典型的订阅发布模式。BScrollCore 作为一个最小的滚动单元,内部也是存在非常多的功能类,每个功能类都有一个叫 hooks 的属性,它架起了不同类之间沟通的桥梁。如果你要编写一个复杂的插件,钩子是必须需要掌握的内容。

  • BScrollCore.hooks

    • beforeInitialScrollTo

      • 触发时机:初始化加载完插件,需要滚动到指定位置

      • 参数

        :position 对象

        • { x: number, y: number }
      • 示例

        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        bs.hooks.on('beforeInitialScrollTo', (postion) => {
          postion.x = 0
          position.y = -200 // 初始化滚动至 -200 的位置
        })
      
    • refresh

      • 触发时机:重新计算 BetterScroll
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        bs.hooks.on('refresh', () => { console.log('refreshed') })
      
    • enable

      • 触发时机:启用 BetterScroll,响应用户行为
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        bs.hooks.on('enable', () => { console.log('enabled') })
      
    • disable

      • 触发时机:禁用 BetterScroll,不再响应用户行为
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        bs.hooks.on('disable', () => { console.log('disabled') })
      
    • destroy

      • 触发时机:销毁 BetterScroll
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        bs.hooks.on('destroy', () => { console.log('destroyed') })
      
    • contentChanged 2.0.4

      • 触发时机:在调用 bs.refresh(),探测到 content DOM 变成了其他元素的时候
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        // bs 版本 >= 2.0.4
        bs.hooks.on('contentChanged', (newContent: HTMLElement) => { console.log(newContent) })
      
  • ActionsHandler.hooks

    • beforeStart

      • 触发时机:刚响应 touchstart 事件,还未记录手指在屏幕点击的位置
      • 参数:event 事件对象
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.actionsHandler.hooks
        hooks.on('beforeStart', (event) => { console.log(event.target) })
      
    • start

      • 触发时机:记录完手指在屏幕点击的位置,即将触发 touchmove
      • 参数:event 事件对象
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.actionsHandler.hooks
        hooks.on('start', (event) => { console.log(event.target) })
      
    • move

      • 触发时机:响应 touchmove 事件,记录完手指在屏幕点击的位置

      • 参数

        :拥有如下属性的对象

        • { number } deltaX:x 方向的手指偏移量
        • { number } deltaY:y 方向的手指偏移量
        • { event } e:event 事件对象
      • 示例

        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.actionsHandler.hooks
        hooks.on('move', ({ deltaX, deltaY, e }) => {})
      
    • end

      • 触发时机:响应 touchend 事件
      • 参数:event 事件对象
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.actionsHandler.hooks
        hooks.on('end', (event) => {})
      
    • click

      • 触发时机:触发 click 事件
      • 参数:event 事件对象
  • ScrollerActions.hooks

    • start

      • 触发时机:记录完所有的滚动初始信息
      • 参数:event 事件对象
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.actions.hooks
        hooks.on('start', (event) => { console.log(event.target) })
      
    • beforeMove

      • 触发时机:在检验是否是合法的滚动之前
      • 参数:event 事件对象
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.actions.hooks
        hooks.on('beforeMove', (event) => { console.log(event.target) })
      
    • scrollStart

      • 触发时机:校验是合法的滚动,并且即将开始滚动
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.actions.hooks
        hooks.on('scrollStart', () => {})
      
    • scroll

      • 触发时机:正在滚动
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.actions.hooks
        hooks.on('scroll', () => {})
      
    • beforeEnd

      • 触发时机:刚执行 touchend 事件回调,但是还未更新最终位置
      • 参数:event 事件对象
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.actions.hooks
        hooks.on('beforeEnd', (event) => { console.log(event) })
      
    • end

      • 触发时机:刚执行 touchend 事件回调并且更新滚动方向

      • 参数

        :两个参数,第一个是 event 事件对象,第二个是当前位置

        • { event } e:事件对象
        • { x: number, y: number } postion:当前位置
      • 示例

        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.actions.hooks
        hooks.on('end', (e, postion) => { console.log(e) })
      
    • scrollEnd

      • 触发时机:滚动即将结束,但还需要校验一次滚动行为是否触发了 flick、momentum 行为。

      • 参数

        :两个参数,第一个是当前位置,第二个是动画时长

        • { x: number, y: number } postion:当前位置
        • { number } duration:动画时长
      • 示例

        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.actions.hooks
        hooks.on('beforeEnd', (pos, duration) => { console.log(pos) })
      
  • Behavior.hooks

    • beforeComputeBoundary

      • 触发时机:即将计算滚动边界

      • 参数

        :boundary 对象

        • { minScrollPos: number, maxScrollPos: number } boundary
      • 示例

        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.scrollBehaviorX.hooks
        hooks.on('beforeComputeBoundary', () => {})
      
    • computeBoundary

      • 触发时机:计算滚动边界
      • 示例
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.scrollBehaviorX.hooks
        hooks.on('computeBoundary', (boundary) => {
          console.log(boundary.minScrollPos) // 上边界最大值,正的越多,下拉的幅度越大
          console.log(boundary.maxScrollPos) // 下边界最小值,负的越多,滚的越远
        })
      
    • momentum

      • 触发时机:满足触发 momentum 动量动画条件,并且在计算之前

      • 参数

        :两个参数,第一个是 momentumData 对象,第二个是滚动偏移量

        • { destination: number, duration: number, rate: number} momentumData:destination 是目标位置,duration 是缓动时长,rate 是斜率
        • { number } distance:触发 momentum 的滚动偏移量
      • 示例

        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.scrollBehaviorX.hooks
        hooks.on('momentum', (momentumData, distance) => {})
      
    • end

      • 触发时机:不满足触发 momentum 动量动画条件

      • 参数

        :momentumInfo 对象

        • { destination: number, duration: number} momentumInfo:destination 是目标位置,duration 是缓动时长
      • 示例

        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.scrollBehaviorX.hooks
        hooks.on('end', (momentumInfo) => {
          console.log(momentumInfo.destination)
          console.log(momentumInfo.duration)
        })
      
  • Animation.hooks(useTransition: false)

    • forceStop

      • 触发时机:强制让一个滚动的 bs 停止

      • 参数

        :position 对象

        • { x: number, y: number } position:当前坐标值
    • move

      • 触发时机:滚动进行中

      • 参数

        :position 对象

        • { x: number, y: number } position:当前坐标值
    • end

      • 触发时机:滚动结束

      • 参数

        :position 对象

        • { x: number, y: number } position:当前坐标值
  • Translater.hooks

    • beforeTranslate

      • 触发时机:在修改 content 元素的 transform style 之前,zoom 插件监听了钩子

      • 参数

        :第一个是 transformStyle 数组,第二个是 point 对象

        • { ['translateX(0px)'|'translateY(0px)'] } transformStyle:当前 transform 对应的属性值
        • { x: number, y: number } point:x 对应 translateX 的值,y 对应 translateY 的值
          import BScroll from '@better-scroll/core'
          const bs = new BScroll('.wrapper', {})
          const hooks = bs.scroller.translater.hooks
          hooks.on('beforeTranslate', (transformStyle, point) => {
            transformStyle.push('scale(1.2)')
            console.log(transformStyle) // ['translateX(0px)', 'translateY(0px)', 'scale(1.2)']
            console.log(point) // { x: 0, y: 0 }
          })
        
    • translate

      • 触发时机:修改 content 元素的 transform style 之后,wheel 插件监听了钩子

      • 参数

        :point 对象

        • { x: number, y: number } point:x 对应 translateX 的值,y 对应 translateY 的值
          import BScroll from '@better-scroll/core'
          const bs = new BScroll('.wrapper', {})
          const hooks = bs.scroller.translater.hooks
          hooks.on('translate', (point) => {
            console.log(point) // { x: 0, y: 0 }
          })
        
  • Transition.hooks(useTransition: true)

    • forceStop

      • 触发时机:强制让一个正在做动画的 bs 停止

      • 参数

        :position 对象

        • { x: number, y: number } position:当前坐标值
    • move

      • 触发时机:滚动进行中

      • 参数

        :position 对象

        • { x: number, y: number } position:当前坐标值
    • end

      • 触发时机:滚动结束

      • 参数

        :position 对象

        • { x: number, y: number } position:当前坐标值
    • time

      • 触发时机:CSS3 transition 开始之前,wheel 插件监听了该钩子

      • 参数

        :CSS3 transition duration

          import BScroll from '@better-scroll/core'
          const bs = new BScroll('.wrapper', {})
          const hooks = bs.scroller.animater.hooks
          hooks.on('time', (duration) => {
            console.log(duration) // 800
          })
        
    • timeFunction

      • 触发时机:CSS3 transition 开始之前,wheel 插件监听了该钩子

      • 参数

        :CSS3 transition-timing-function

          import BScroll from '@better-scroll/core'
          const bs = new BScroll('.wrapper', {})
          const hooks = bs.scroller.animater.hooks
          hooks.on('timeFunction', (easing) => {
            console.log(easing) // cubic-bezier(0.1, 0.7, 1.0, 0.1)
          })
        
  • Scroller.hooks

    • beforeStartScrollerActions.hooks.start

    • beforeMoveScrollerActions.hooks.beforeMove

    • beforeScrollStartScrollerActions.hooks.start

    • scrollStartScrollerActions.hooks.scrollStart

    • scroll

      • 触发时机:滚动进行中

      • 参数

        :position 对象

        • { x: number, y: number } position:当前坐标值
    • beforeEndScrollerActions.hooks.beforeEnd

    • touchEnd

      • 触发时机:用户手指离开滚动区域
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.hooks
        hooks.on('touchEnd', () => {
          console.log('your finger has leave')
        })
      
    • end

      • 触发时机:touchEnd 之后,校验 click 之前触发,pull-down 插件基于这个钩子实现
      • 参数:position 对象
      • { x: number, y: number } position:当前位置
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.hooks
        hooks.on('end', (position) => {
          console.log(position.x)
          console.log(position.y)
        })
      
    • scrollEnd

      • 触发时机:滚动结束

      • 参数

        :position 对象

        • { x: number, y: number } position:当前坐标值
    • resize

      • 触发时机:window 尺寸发生改变
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.hooks
        hooks.on('resize', () => {
          console.log("window's size has changed")
        })
      
    • flick

      • 触发时机:探测到手指轻拂动作
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.hooks
        hooks.on('flick', () => {})
      
    • scrollCancel

      • 触发时机:滚动取消或者未发生
    • momentum

      • 触发时机:即将进行 momentum 动量位移,slide 插件监听了该钩子

      • 参数

        :scrollMetaData 对象

        • { time: number, easing: EaseItem, newX: number, newY: number }:time 是动画时长,easing是缓动函数,newX 和 newY 是终点
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.hooks
        hooks.on('momentum', (scrollMetaData) => {
          scrollMetaData.newX = 0
          scrollMetaData.newY = -200
        })
      
    • scrollTo

      • 触发时机:调用 bs.scrollTo 方法的时候触发

      • 参数

        :endPoint 对象

        • { x: number, y: number } endPoint:终点坐标值
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.hooks
        hooks.on('scrollTo', (endPoint) => {
          console.log(endPoint.x)
          console.log(endPoint.y)
        })
        bs.scrollTo(0, -200)
      
    • scrollToElement

      • 触发时机:调用 bs.scrollToElement 方法的时候触发,wheel 插件监听了该钩子

      • 参数

        :第一个是目标 DOM 对象,第二个是终点的坐标

        • { HTMLElment } el
        • { top: number, left: number } postion
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.hooks
        hooks.on('scrollToElement', (el, pos) => {
          console.log(el)
          console.log(pos.left)
          console.log(pos.top)
        })
        bs.scrollToElement('.some-item', 300, true, true)
      
    • beforeRefresh

      • 触发时机:在 behavior 计算边界之前,slide 插件监听了该钩子
        import BScroll from '@better-scroll/core'
        const bs = new BScroll('.wrapper', {})
        const hooks = bs.scroller.hooks
        hooks.on('beforeRefresh', () => {})
      
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值