☰
Locomotive Scroll 实例方法完全指南:destroy、start、stop、resize、scrollTo 与动态元素管理
2026/9/25 3:04:19 网站建设 项目流程

【免费下载链接】locomotive-scroll

🛤 Detection of elements in viewport & smooth scrolling with parallax.

项目地址:https://gitcode.com/gh_mirrors/lo/locomotive-scroll
点击查看免费下载

本文是 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()手动触发尺寸重算
动态 DOMremoveScrollElements()/addScrollElements()对容器内的[data-scroll]元素取消/建立观察
定向滚动scrollTo()平滑滚动到指定目标

其中start()、stop()、resize()、scrollTo()均是薄封装,最终转发给内部 Lenis 实例与 Core 实例;removeScrollElements()与addScrollElements()则贯穿事件绑定、Intersection Observer 与内部元素列表三套数据结构。

destroy():完整销毁实例

const locomotiveScroll = new LocomotiveScroll(); locomotiveScroll.destroy();

destroy()用于销毁 Locomotive Scroll 实例及其关联事件,适合在卸载页面、切换路由或彻底清理功能时调用。从 源码实现 可以看到它的执行顺序是严格分层的:

  1. 先停:调用this.stop(),停止 RAF 循环并调用 Lenis 的stop();
  2. 解绑事件:_unbindEvents()移除所有data-scroll-to点击监听,并把 Lenis dimensions 的 resize 回调 恢复为原始函数(_bindEvents曾将其包装以联动 Locomotive 的重算);
  3. 销毁 Lenis:this.lenisInstance?.destroy();
  4. 延迟销毁 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)依次完成:

  1. 空参校验,$oldContainer缺失时console.error;
  2. _unbindScrollToEvents($oldContainer):解绑容器内所有data-scroll-to元素的 click 监听;
  3. Core 层用querySelectorAll('[data-scroll]')收集待移除元素并转为Set去重;
  4. 从triggeredScrollElements/RAFScrollElements数组中剔除对应实例,并调用IO.unobserve()(见 packages/lib/core/IO.ts#L106-L112)让 Intersection Observer 停止观察;
  5. 从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)逻辑相反:

  1. 在 Core 层收集容器内所有[data-scroll]元素;
  2. 计算当前全量列表的最大id,新元素从maxID + 1开始分配自增 id(保证动态加入的元素 id 全局唯一);
  3. 为每个元素创建新的ScrollElement实例,并根据是否需要 RAF 分发到对应数组,同时动态调用IO.observe()建立观察;
  4. 回到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 中定义为:

选项类型说明
offsetnumber相当于 CSSscroll-padding-top,目标元素顶部的偏移量
lerpnumber动画的 lerp(线性插值)强度
durationnumber滚动动画时长(秒)
immediateboolean为true时忽略 duration 与 easing,立即滚动
lockboolean是否在到达目标前阻止用户手动滚动
forceboolean即使实例已stop()也强制到达目标
easingfunction缓动函数,签名(t: number) => number
onCompletefunction到达目标时回调

从 scrollTo 实现 可以看到,方法本身不做任何计算,而是将这 8 个选项原样透传给lenisInstance.scrollTo(),由 Lenis 完成动画与物理插值。

与>

【免费下载链接】locomotive-scroll

🛤 Detection of elements in viewport & smooth scrolling with parallax.

项目地址:https://gitcode.com/gh_mirrors/lo/locomotive-scroll
点击查看免费下载
上一篇:Haystack DeepEvalEvaluator 集成指南:用 DeepEval 指标评估 RAG 流水线
下一篇:ZoneMTA vs Postfix vs Haraka:为什么选择这款 Node.js 邮件中继服务器?

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询