【免费下载链接】locomotive-scroll
🛤 Detection of elements in viewport & smooth scrolling with parallax.
本文是 Locomotive Scroll 官方文档中 Methods 一章的深度实践指南,系统讲解LocomotiveScroll实例的 7 个公开方法:destroy()、start()、stop()、resize()、removeScrollElements($oldContainer)、addScrollElements($newContainer)与scrollTo(target, options)。结合本仓库 入口实现 与 核心模块 的源码,你将掌握每个方法的参数语义、生命周期顺序、底层调用链,以及如何在 SPA / Ajax 动态渲染场景中正确增删滚动元素。
方法总览
所有公开方法都定义在LocomotiveScroll类上(见 packages/lib/index.ts),它们按职责可划分为三组:
| 分组 | 方法 | 职责 |
|---|---|---|
| 生命周期 | destroy() | 销毁实例并解绑所有事件 |
| 运行控制 | start()/stop() | 手动启停内部 RAF(渲染循环) |
| 布局同步 | resize() | 手动触发尺寸重算 |
| 动态 DOM | removeScrollElements()/addScrollElements() | 对容器内的[data-scroll]元素取消/建立观察 |
| 定向滚动 | scrollTo() | 平滑滚动到指定目标 |
其中start()、stop()、resize()、scrollTo()均是薄封装,最终转发给内部 Lenis 实例与 Core 实例;removeScrollElements()与addScrollElements()则贯穿事件绑定、Intersection Observer 与内部元素列表三套数据结构。
destroy():完整销毁实例
const locomotiveScroll = new LocomotiveScroll(); locomotiveScroll.destroy();destroy()用于销毁 Locomotive Scroll 实例及其关联事件,适合在卸载页面、切换路由或彻底清理功能时调用。从 源码实现 可以看到它的执行顺序是严格分层的:
- 先停:调用
this.stop(),停止 RAF 循环并调用 Lenis 的stop(); - 解绑事件:
_unbindEvents()移除所有data-scroll-to点击监听,并把 Lenis dimensions 的 resize 回调 恢复为原始函数(_bindEvents曾将其包装以联动 Locomotive 的重算); - 销毁 Lenis:
this.lenisInstance?.destroy(); - 延迟销毁 Core:通过
requestAnimationFrame在下一帧执行this.coreInstance?.destroy()。源码注释明确指出这是为了避免 destroy 与排队中的 Intersection Observer 回调产生竞态条件。
Core 层的销毁(packages/lib/core/Core.ts#L116-L120)会断开触发型与 RAF 型两个 Intersection Observer,并清空全部内部数组;随后每个ScrollElement的 destroy() 还会做 DOM 级清理:移除--progressCSS 变量、移除 parallax 设置的transform、移除进入视口时添加的is-inview类,避免内存泄漏与样式残留。
start() 与 stop():手动控制渲染循环
默认情况下,创建实例后渲染循环会自动启动(由autoStart选项控制,默认true)。如果你需要程序化地控制启动时机,可以关闭自动启动再手动调用start():
const locomotiveScroll = new LocomotiveScroll({ autoStart: false }); // 在下一帧启动 requestAnimationFrame(() => { locomotiveScroll.start(); });对应地,stop()让滚动运动停下来:
const locomotiveScroll = new LocomotiveScroll(); // 在下一帧停止 requestAnimationFrame(() => { locomotiveScroll.stop(); });底层逻辑见 packages/lib/index.ts#L284-L313:
- 两个方法都以
this.rafPlaying布尔标志做幂等保护,重复调用不会产生副作用; start()先调用lenisInstance.start()恢复 Lenis 平滑滚动,再决定渲染驱动方式:若配置了initCustomTicker,则把渲染回调交给外部 ticker(例如 GSAP 的gsap.ticker);否则启动自有的requestAnimationFrame循环_raf(),每帧执行_onRender()——先驱动 Lenis 的raf(Date.now()),再让 Core 对所有处于交互状态的滚动元素做进度计算(见 packages/lib/index.ts#L248-L255);stop()是对称操作:调用lenisInstance.stop(),再调用destroyCustomTicker或cancelAnimationFrame。
提示:
autoStart: false的完整配置说明与示例见 Options 文档。若只配置initCustomTicker或只配置destroyCustomTicker,源码会在初始化时输出console.warn警告,两者必须成对声明。
resize():手动触发尺寸重算
const locomotiveScroll = new LocomotiveScroll(); locomotiveScroll.resize();resize()手动触发实例的 resize 回调,适合在布局动态变化后主动刷新滚动计算。它的实现非常轻量——packages/lib/index.ts#L346-L348 中直接调用绑定的_onResize,后者把当前滚动值与smooth(触摸设备为false)传给 Core 的 onResize,Core 再遍历所有需要 RAF 的ScrollElement重新计算getBoundingClientRect、元素度量与交区间。
需要特别说明的是:大部分场景下你不需要手动调用它。实例初始化时_bindEvents()会钩住 Lenis dimensions 的两个 ResizeObserver 回调onContentResize(内容尺寸变化,如图片加载、动态内容插入)与onWrapperResize(容器尺寸变化,如窗口缩放、布局变更),在它们触发后自动联动重算(packages/lib/index.ts#L164-L181)。因此文档给出的建议是:仅在 Lenis 检测不到的动态布局变更时,才需要手动resize()。
removeScrollElements($oldContainer) 与 addScrollElements($newContainer):动态 DOM 的观察管理
SPA 或 Ajax 页面中,内容会被反复增删。由于实例初始化时只观察初始 DOM 中的[data-scroll]元素,新插入的元素不会被追踪、已移除的元素会残留监听。这两个方法就是为了解决该问题而设计的。
移除旧容器中的滚动元素
const locomotiveScroll = new LocomotiveScroll(); const $oldContainer = document.getElementById('containerToRemove'); locomotiveScroll.removeScrollElements($oldContainer);- 参数:
$oldContainer(HTMLElement)——已被移出 DOM 的父容器,其中包含需要取消观察的[data-scroll]元素。
removeScrollElements的调用链(packages/lib/index.ts#L318-L326 → packages/lib/core/Core.ts#L150-L195)依次完成:
- 空参校验,
$oldContainer缺失时console.error; _unbindScrollToEvents($oldContainer):解绑容器内所有data-scroll-to元素的 click 监听;- Core 层用
querySelectorAll('[data-scroll]')收集待移除元素并转为Set去重; - 从
triggeredScrollElements/RAFScrollElements数组中剔除对应实例,并调用IO.unobserve()(见 packages/lib/core/IO.ts#L106-L112)让 Intersection Observer 停止观察; - 从
scrollElementsToUpdate(每帧参与 RAF 计算的元素)与scrollElements(全量列表)中清理对应项。
添加新容器中的滚动元素
const locomotiveScroll = new LocomotiveScroll(); const $newContainer = document.getElementById('containerToAdd'); locomotiveScroll.addScrollElements($newContainer);- 参数:
$newContainer(HTMLElement)——新插入 DOM 的父容器,其中包含需要观察的[data-scroll]元素。
其调用链(packages/lib/index.ts#L331-L341 → packages/lib/core/Core.ts#L202-L219)逻辑相反:
- 在 Core 层收集容器内所有
[data-scroll]元素; - 计算当前全量列表的最大
id,新元素从maxID + 1开始分配自增 id(保证动态加入的元素 id 全局唯一); - 为每个元素创建新的
ScrollElement实例,并根据是否需要 RAF 分发到对应数组,同时动态调用IO.observe()建立观察; - 回到
LocomotiveScroll层后,通过requestAnimationFrame在下一次渲染前为容器内的data-scroll-to元素绑定 click 监听。
典型场景:Ajax 内容替换
async function loadSection(url, $container) { // 1. 移除旧内容对应的滚动元素 locomotiveScroll.removeScrollElements($container); // 2. 拉取并替换 DOM const html = await fetch(url).then(r => r.text()); $container.innerHTML = html; // 3. 观察新内容中的滚动元素 locomotiveScroll.addScrollElements($container); }配合data-scroll-call、data-scroll-event-progress等回调(见 Attributes 文档),即可在动态内容上完整恢复视口检测、视差与进度动画能力。
scrollTo(target, options):定向平滑滚动
scrollTo(target, options)是实例最常用的导航方法,滚动到页面中的指定目标:
import LocomotiveScroll from 'locomotive-scroll'; const locomotiveScroll = new LocomotiveScroll(); const $target = document.getElementById('jsTarget'); function scrollTo(params) { const { target, options } = params; locomotiveScroll.scrollTo(target, options); } scrollTo({ target: $target, options: {} });target 参数
target为可选参数,类型为number | HTMLElement | string(见 packages/lib/types.ts#L25),三种取值等价:
- number:直接指定滚动位置(像素);
- HTMLElement:滚动到某个 DOM 元素;
- string:CSS 选择器,或关键字
top、left、start、bottom、right、end。
options 参数
options为可选参数,类型为ILenisScrollToOptions,在 packages/lib/types.ts#L51-L60 中定义为:
| 选项 | 类型 | 说明 |
|---|---|---|
offset | number | 相当于 CSSscroll-padding-top,目标元素顶部的偏移量 |
lerp | number | 动画的 lerp(线性插值)强度 |
duration | number | 滚动动画时长(秒) |
immediate | boolean | 为true时忽略 duration 与 easing,立即滚动 |
lock | boolean | 是否在到达目标前阻止用户手动滚动 |
force | boolean | 即使实例已stop()也强制到达目标 |
easing | function | 缓动函数,签名(t: number) => number |
onComplete | function | 到达目标时回调 |
从 scrollTo 实现 可以看到,方法本身不做任何计算,而是将这 8 个选项原样透传给lenisInstance.scrollTo(),由 Lenis 完成动画与物理插值。
与>赞
【免费下载链接】locomotive-scroll
🛤 Detection of elements in viewport & smooth scrolling with parallax.
相关推荐
Designable 自定义设置器开发:扩展设计工具功能的终极指南
Designable 自定义设置器开发:扩展设计工具功能的终极指南 Designable 是一款功能强大的设计工具开发框架,允许开发者通过自定义设置器扩展其功能
locomotive-scroll中的Web Components:自定义滚动元素
locomotive scroll中的Web Components:自定义滚动元素 在现代Web开发中,滚动体验是用户交互的核心部分。locomotive sc
革命性视差滚动引擎locomotive-scroll:让元素检测与平滑滚动完美融合
革命性视差滚动引擎locomotive scroll:让元素检测与平滑滚动完美融合 你还在为网页滚动效果单调而烦恼?还在为元素进入视口时缺乏动态反馈而头疼?lo