packages/vuepress-docs/docs/en-US/guide/base-scroll-api.md
If you want to understand BetterScroll thoroughly, you need to understand the common properties of its instances, the flexible methods, and the hooks provided.
Sometimes we want to do some extensions based on BetterScroll, we need to understand some of the properties of BetterScroll. Here are a few common properties.
number.number.numbernumbernumbernumbernumbernumbernumbernumberboolean,boolean,BetterScroll provides a lot of flexible APIs, which are used when we implement some features based on BetterScroll, and understanding them will help to meet more complex requirements.
{number} x, horizontal axis distance. (unit: px){number} y, vertical axis distance. (unit: px){number} time, animation duration. (unit: ms){Object} easing function, usually don't suggest modifying. If you really need to modify, please refer packages/shared-utils/src/ease.ts's of source code{Object} extraTransform, you only need to pass in this parameter if you want to modify some other properties of the CSS transform. The structure is as follows:let extraTransform = {
// start point
start: {
scale: 0
},
// end poinnt
end: {
scale: 1.1
}
}
bs.scrollTo(0, -60, 300, undefined, extraTransform)
- **Return**: none.
- **Usage**: scroll to specified position.
{number} x, horizontal axis changed distance. (unit: px){number} y, vertical axis changed distance. (unit: px){number} time, animation duration. (unit: ms){Object} easing function, usually don't suggest modifying. If you really need to modify, please refer packages/shared-utils/src/ease.ts.{DOM | string} el, target element. If the value is a string, we will try to use querySelector get the DOM element.{number} time, animation duration. (unit ms){number | boolean} offsetX, the x offset to target element,If the value is true, scroll to the center of target element.{number | boolean} offsetY, the y offset to target element,If the value is true, scroll to the center of target element.{Object} easing function, usually don't suggest modifying. If you really need to modify, please refer packages/shared-utils/src/ease.ts.{string} type, event{Function} fn, callback{Object} context,default is this.import BScroll from '@BetterScroll/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)
{string} type, event{Function} fn, callback{Object} context, default is this.{string} type, event{Function} fn, callbackimport BScroll from '@BetterScroll/core'
let scroll = new BScroll('.wrapper', {
probeType: 3
})
function handler() {
console.log('bs is scrolling now')
}
scroll.on('scroll', handler)
scroll.off('scroll', handler)
Based on the 2.x architecture design and compatibility with 1.x events, we have extended two concepts-"Events" and "Hooks". Basically, they are all instances of EventEmitter, but they are called differently. Let's explain it from the excerpted source code below:
export default BScrollCore extends EventEmitter {
hooks: EventEmitter
}
BScrollCore
It inherits EventEmitter itself. we all call it "event".
import BScroll from '@better-scroll/core'
let bs = new BScroll('.wrapper', {})
// listen bs scroll event
bs.on('scroll', () => {})
// listen bs refresh event
bs.on('refresh', () => {})
BScrollCore.hooks
Hooks are also instances of EventEmitter. we all call it "hook".
import BScroll from '@better-scroll/core'
let bs = new BScroll('.wrapper', {})
// tap bs refresh hook
bs.hooks.on('refresh', () => {})
// tap bs enable hook
bs.hooks.on('enable', () => {})
I believe everyone now has a better distinction between the two. "Event" is for the compatibility of 1.x. Users generally pay attention to the distribution of events, but if you want to write a plugin, you should focus on "hooks".
In 2.0, BetterScroll events are almost same with 1.x events. Only BetterScroll will dispatch "events". If you need to expose events when writing plugins, you should also dispatch them through BetterScroll. details is here, the current events are divided into the following types:
refresh
import BetterScroll from '@better-scroll/core'
const bs = new BetterScroll('.wrapper', {})
bs.on('refresh', () => {})
enable
bs.on('enable', () => {})
disable
bs.on('disable', () => {})
beforeScrollStart
bs.on('beforeScrollStart', () => {})
scrollStart
bs.on('scrollStart', () => {})
scroll
bs.on('scroll', (position) => {
console.log(position.x, position.y)
})
scrollEnd
bs.on('scrollEnd', () => {})
scrollCancel
bs.on('scrollCancel', () => {})
touchEnd
bs.on('touchEnd', () => {})
flick
bs.on('flick', () => {})
destroy
bs.on('destroy', () => {})
contentChanged <Badge text='2.0.4' />
bs.refresh(), it is detected that the content DOM has become other elements // bs version >= 2.0.4
bs.on('contentChanged', (newContent: HTMLElement) => {})
The following events must be registered for the plugin in parentheses to be dispatched:
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
* mouseWheelOptions.easeTime
* mouseWheelOptions.discreteTime
* mouseWheelOptions.throttleTime
* mouseWheelOptions.dampingFactor
**/
// please see details in mouse-wheel plugin doc
})
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)
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) => {
// Page about to switch
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 }) => {
// current scale
})
zoomEnd(zoom)
bs.on('zoomEnd', ({ scale }) => {})
A hook is a concept extended from version 2.0. Its essence is the same as an event. It is an instance of EventEmitter, which is a typical subscription publishing model. As the smallest scroll unit, BScrollCore also has many functional classes inside. Each functional class has a property called hooks, which bridges the communication between different classes. If you want to write a complex plugin, hooks must be mastered.
BScrollCore.hooks
beforeInitialScrollTo
{ 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 // Initialize scroll to -200
})
refresh
import BScroll from '@better-scroll/core'
const bs = new BScroll('.wrapper', {})
bs.hooks.on('refresh', () => { console.log('refreshed') })
enable
import BScroll from '@better-scroll/core'
const bs = new BScroll('.wrapper', {})
bs.hooks.on('enable', () => { console.log('enabled') })
disable
import BScroll from '@better-scroll/core'
const bs = new BScroll('.wrapper', {})
bs.hooks.on('disable', () => { console.log('disabled') })
destroy
import BScroll from '@better-scroll/core'
const bs = new BScroll('.wrapper', {})
bs.hooks.on('destroy', () => { console.log('destroyed') })
contentChanged <Badge text='2.0.4' />
bs.refresh(), it is detected that the content DOM has become other elements import BScroll from '@better-scroll/core'
const bs = new BScroll('.wrapper', {})
// bs version >= 2.0.4
bs.hooks.on('contentChanged', (newContent: HTMLElement) => { console.log(newContent) })
ActionsHandler.hooks
beforeStart
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
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
{ number } deltaX: x offset{ number } deltaY: y offset{ event } e: event object import BScroll from '@better-scroll/core'
const bs = new BScroll('.wrapper', {})
const hooks = bs.scroller.actionsHandler.hooks
hooks.on('move', ({ deltaX, deltaY, e }) => {})
end
import BScroll from '@better-scroll/core'
const bs = new BScroll('.wrapper', {})
const hooks = bs.scroller.actionsHandler.hooks
hooks.on('end', (event) => {})
click
ScrollerActions.hooks
start
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
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
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
{ event } e: event object{ x: number, y: number } postion: current position 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
{ x: number, y: number } postion: current position{ number } duration: animation 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) })
coordinateTransformation
{ deltaX: number, deltaY: number } transformateDeltaDatalet bs = new BScroll('.wrapper', {
quadrant: 1 // default value
})
bs.scroller.actions.hooks.on(
'coordinateTransformation',
(transformateDeltaData) => {
// get user finger moved distance
const originDeltaX = transformateDeltaData.deltaX
const originDeltaY = transformateDeltaData.deltaY
// apply transformation
transformateDeltaData.deltaX = originDeltaY
transformateDeltaData.deltaY = originDeltaX
// transformateDeltaData.deltaX will be used as content DOM style's translateX
// transformateDeltaData.deltaY will be used as content DOM style's translateY
}
)
This hook is usually to fix the logic of user-defined displacement transformation when the ancestor element of the wrapper DOM of BetterScroll is rotated. In most cases, it only needs to be configured quadrant.
Behavior.hooks
beforeComputeBoundary
{ 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) => {
// The maximum value of the upper boundary, the more positive, the greater the pull down
console.log(boundary.minScrollPos)
// The minimum value of the lower boundary, the more negative, the farther you roll
console.log(boundary.maxScrollPos)
})
momentum
{ destination: number, duration: number, rate: number} momentumData: destination is the target position, duration is the easing time, rate is the slope{ number } distance: Scroll offset to trigger momentum import BScroll from '@better-scroll/core'
const bs = new BScroll('.wrapper', {})
const hooks = bs.scroller.scrollBehaviorX.hooks
hooks.on('momentum', (momentumData, distance) => {})
end
{ destination: number, duration: number} momentumInfo: destination is the target position, duration is the easing time 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
{ x: number, y: number } positionmove
{ x: number, y: number } positionend
{ x: number, y: number } positionTransition.hooks(useTransition: true)
forceStop
{ x: number, y: number } positionmove
{ x: number, y: number } positionend
{ x: number, y: number } positiontime
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
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)
})
Translater.hooks
beforeTranslate
{ ['translateX(0px)'|'translateY(0px)'] } transformStyle: The property value corresponding to the current transform{ x: number, y: number } point: x corresponds to the value of translateX, y corresponds to the value of 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
{ x: number, y: number } point: x corresponds to the value of translateX, y corresponds to the value of 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 }
})
Scroller.hooks
beforeStart
same with ScrollerActions.hooks.start
beforeMove
same with ScrollerActions.hooks.beforeMove
beforeScrollStart
same with ScrollerActions.hooks.start
scrollStart
same with ScrollerActions.hooks.scrollStart
scroll
{ x: number, y: number } positionbeforeEnd
same with ScrollerActions.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
{ 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
{ x: number, y: number } positionresize
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
{ time: number, easing: EaseItem, newX: number, newY: number }: time is the duration of the animation, easing is the easing function, newX and newY are the end points 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
{ 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
{ 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
import BScroll from '@better-scroll/core'
const bs = new BScroll('.wrapper', {})
const hooks = bs.scroller.hooks
hooks.on('beforeRefresh', () => {})
::: tip If you are careful, you will find that some Scroller.hooks have exactly the same functions as ScrollActions.hooks. In fact, we internally use a hook bubbling strategy to proxy the hooks of the inner function classes to the BetterScroll Instance in the form of bubbling to be compatible with the use of 1.x. :::