- 前端
- UI组件
【免费下载链接】better-scroll
:scroll: inspired by iscroll, and it supports more features and has a better scroll perfermance
BetterScroll 2.x 采用「最小核心 + 插件化」的架构设计,用户可以根据业务诉求在「基础滚动(core)」「增强型滚动(core + 插件)」「全能力滚动(better-scroll 全家桶)」三档方案中自由选择。本文以官方文档 use.md 为主线,结合仓库源码讲解三种使用方式的差异、插件注册机制与底层原理,读完你即可按需搭建任意复杂度的滚动场景。
三种使用方式概览
BetterScroll 2.x 将能力拆分为三层,选择哪一档取决于你的功能需求与对包体积的敏感度:
| 使用方式 | 引入的包 | 能力范围 | 包体积 |
|---|---|---|---|
| 基础滚动 | @better-scroll/core | 仅核心滚动(垂直/水平/自由滚动、回弹、惯性等) | 最小,比 1.x 压缩体积小近三分之一 |
| 增强型滚动 | @better-scroll/core+ 各功能插件 | 核心滚动 + 按需插件(pull-up、pull-down、scroll-bar 等) | 随插件数量增长,可按需控制 |
| 全能力滚动 | better-scroll | 一次引入全部插件能力,用法与 1.x 完全一致 | 最大,且随功能扩展持续增长 |
官方文档明确建议:除非业务确实需要全部插件能力,否则推荐按需引入,避免 bundle 体积失控。
基础滚动:只引入 core
如果你只需要一个拥有基础滚动能力的列表,只需要引入@better-scroll/core:
import BScroll from '@better-scroll/core' let bs = new BScroll('.wrapper', { // ...... 详见配置项 })@better-scroll/core是 BetterScroll 2.x 的最小使用单元,其 package.json 中描述为 "Minimalistic core scrolling for BetterScroll, it is pure and tiny",仅依赖@better-scroll/shared-utils一个包。核心类BScrollConstructor位于 BScroll.ts,构造函数接收两个参数:
- el:wrapper 元素,可以是 DOM 节点也可以是 CSS 选择器字符串(内部通过
getElement解析); - options:配置对象,与用户传入配置合并后经
process()加工生效。
基础滚动的三种模式
官方文档在 base-scroll.md 中归纳了三种基础滚动模式:
- 垂直滚动(默认):
scrollY默认为true,可直接滚出一个纵向列表; - 水平滚动:需要
scrollX: true,同时对 CSS 有严格要求——wrapper 必须保证不换行(white-space: nowrap),content 的display必须是inline-block; - freeScroll(水平与垂直同时滚动):设置
freeScroll: true后,从源码 Options.ts 可以看到,process()会把scrollX与scrollY强制置为true,允许任意方向滚动。
.scroll-wrapper // ... white-space nowrap .scroll-content // ... display inline-block核心配置项的默认值与含义
从 Options.ts 的OptionsConstructor构造器中可以看到完整的默认配置,以下是与基础滚动强相关的关键项:
| 配置项 | 默认值 | 说明 |
|---|---|---|
scrollX/scrollY | false/true | 是否开启横向 / 纵向滚动 |
freeScroll | false | 开启后同时允许 X / Y 两个方向滚动 |
startX/startY | 0/0 | 初始滚动位置 |
bounce | {top: true, right: true, bottom: true, left: true} | 是否回弹,可传布尔或对象 |
bounceTime | 800 | 回弹动画时长(ms) |
momentum | true | 是否开启惯性滚动 |
momentumLimitTime | 300 | 触发惯性的最短触摸时长(ms) |
momentumLimitDistance | 15 | 触发惯性的最短触摸距离(px) |
deceleration | 0.0015 | 惯性滚动减速度 |
probeType | 0(Probe.Default) | 滚动事件探测粒度,详见下文 |
click | false | 是否派发原生 click 事件 |
tap | '' | 是否派发自定义 tap 事件 |
useTransition | true | 是否使用 CSS3 transition 实现动画 |
specifiedIndexAsContent | 0 | 指定 wrapper 的第几个子元素作为 content(2.0.4+) |
quadrant | Quadrant.First | 父元素旋转时的交互修正(2.3.0+) |
::: warning BetterScroll 实时派发 scroll 事件,需要将probeType设置为 3。probeType的取值对应 shared-utils 中的Probe枚举:0为默认(不派发实时 scroll),1为滚动过程中派发(节流),2与3均为实时派发(3还用于插件强制实时探测)。 :::
增强型滚动:core + 按需插件
如果你需要额外 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 })注意两个关键点:
BScroll.use(Plugin)必须在new BScroll()之前调用;- 配置项的键名(如
pullUpLoad)必须与插件类上的静态属性pluginName一致,否则插件无法实例化。
插件注册的源码机制
从 BScroll.ts 的静态方法use()可以看到完整注册流程:
- 校验插件是否已安装(重复注册直接返回);
- 校验插件类是否声明了静态属性
pluginName,未声明时输出警告并拒绝注册; - 将插件存入
BScroll.plugins数组与pluginsMap映射表,支持链式调用.use().use()。
在new BScroll()时,构造函数会把插件实例化到bs.plugins上;插件通过scroll.proxy(propertiesConfig)将方法、属性代理到bs实例,通过scroll.registerType([...])注册自定义事件类型。以 pull-up 插件 为例,其static pluginName = 'pullUpLoad'与propertiesConfig中的proxy配置,使你可以直接在bs上调用bs.finishPullUp()、bs.openPullUp()、bs.autoPullUpLoad()等方法,并监听bs.on('pullingUp', handler)事件。另一个细节:插件在handleOptions()中会把scroll.options.probeType强制设为Probe.Realtime(值 3),以保证滚动位置的实时探测。
插件如何暴露方法、属性与事件
插件中暴露的方法与属性,在执行new BScroll()之后会通过Object.defineProperty代理到bs。以 zoom 插件为例:
import BScroll from '@better-scroll/core' import Zoom from '@better-scroll/zoom' BScroll.use(Zoom) const bs = new BScroll('#scroll-wrapper', { freeScroll: true, scrollX: true, scrollY: true, disableMouse: true, useTransition: true, zoom: { start: 1, min: 0.5, max: 2 } }) bs.zoomTo(1.5, 0, 0) // 不用关心 zoom 插件实例,直接通过 bs 获取暴露的方法 bs.on('zoomStart', zoomStartHandler) // 插件事件同样代理至 bs插件全部内置插件清单见 plugins/README.md:pulldown、pullup、scrollbar、slide、wheel、zoom、mouse-wheel、observe-dom、observe-image、nested-scroll、infinity、movable、indicators。若确实需要操作插件实例本身,可通过bs.plugins获取,例如bs.plugins.zoom。
全能力滚动:一次引入所有插件
如果你觉得一个个引入插件很费事,可以使用拥有全部插件能力的better-scroll包:
import BScroll from 'better-scroll' let bs = new BScroll('.wrapper', { // ... pullUpLoad: true, wheel: true, scrollbar: true, // and so on })它的使用方式与 1.0 版本一模一样,但体积会相对大很多,官方文档明确推荐按需引入。
全能力包内部做了什么
从 better-scroll/src/index.ts 的源码可以清楚看到,这个包本质上是一个「预注册了所有插件的 core」:
- 依赖 13 个功能插件包(见 better-scroll/package.json 的
dependencies,全部为^2.5.1版本); - 在模块加载时依次执行
BScroll.use(...)链式注册 MouseWheel、ObserveDom、PullDownRefresh、PullUpLoad、ScrollBar、Slide、Wheel、Zoom、NestedScroll、InfinityScroll、Movable、ObserveImage、Indicators 共 13 个插件; - 同时 re-export 各插件类(
MouseWheel、PullUpLoad等),方便需要时手动引用。
因此import BScroll from 'better-scroll'得到的对象与@better-scroll/core导出的对象共用同一套插件机制,只是插件已全部就位。你仍然可以直接用pullUpLoad: true、wheel: true、scrollbar: true等配置开启对应能力。
安装与引入方式
NPM / Yarn
npm install @better-scroll/core --save # or yarn add @better-scroll/core全能力包:
npm install better-scroll --save # or yarn add better-scrollES Module 方式(webpack、Rollup 等构建工具均可从 node_modules 引入):
import BScroll from '@better-scroll/core'CommonJS 方式:
var BScroll = require('@better-scroll/scroll')script 标签加载
core 支持直接通过 script 加载,加载后会在window上挂载一个BScroll对象:
<script src="https://unpkg.com/@better-scroll/core@latest/dist/core.js"></script> <!-- minify --> <script src="https://unpkg.com/@better-scroll/core@latest/dist/core.min.js"></script>let wrapper = document.getElementById("wrapper") let bs = new BScroll(wrapper, {})全能力包同样支持 CDN 加载:
<script src="https://unpkg.com/better-scroll@latest/dist/better-scroll.js"></script> <!-- minify --> <script src="https://unpkg.com/better-scroll@latest/dist/better-scroll.min.js"></script>let bs = BetterScroll.createBScroll('.wrapper', {})常见滚动问题排查
官方文档在 base-scroll.md 的「温馨提示」中给出了两条高频问题的排查路径:
- 出现无法滚动的情况:首先检查 content 元素的高度/宽度是否大于 wrapper 的高度/宽度,这是内容能够滚动的前提条件。wrapper 必须有确定的尺寸,且 content 必须超出 wrapper 才会产生可滚动距离。
- 图片导致滚动不正常:如果 content 中存在图片,DOM 渲染时图片可能尚未下载完成,导致 content 高度小于预期。此时应在图片加载完成(如
onload回调)后调用bs.refresh()重新计算滚动距离。refresh是 core 内置事件与实例方法之一(见 BScroll.ts 中注册的事件类型列表)。
小结
- 纯滚动需求:
@better-scroll/core足够,体积最小; - 需要部分增强能力:
@better-scroll/core+ 按需BScroll.use(Plugin),注意pluginName与配置键名一致; - 需要全部能力 / 从 1.x 迁移:直接使用
better-scroll,用法与 1.x 一致,但要接受更大的包体积。
更详细的配置项说明可继续阅读 base-scroll-options.md,插件能力清单见 plugins/README.md,各插件对应的源码与示例位于 packages 目录下对应的子包中。
- 前端
- UI组件
【免费下载链接】better-scroll
:scroll: inspired by iscroll, and it supports more features and has a better scroll perfermance
相关推荐
BProgress核心API解析:start/done/inc方法实现进度精确控制
BProgress核心API解析:start/done/inc方法实现进度精确控制 BProgress是一款轻量级、可定制的进度条工具,专为提升用户体验设计。本
前端UI组件Flipper Authenticator CLI命令完全指南:用命令行高效管理你的全部令牌
Flipper Authenticator CLI命令完全指南:用命令行高效管理你的全部令牌 Flipper Authenticator 是一款运行在 Flip
前端UI组件10个实用案例:Snowflake Arctic-Embed-L OpenMind在企业级检索系统中的应用
10个实用案例:Snowflake Arctic Embed L OpenMind在企业级检索系统中的应用 Snowflake Arctic Embed L O
前端UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考