Locomotive scroll使用data-scroll-call时导航active类重复触发问题
问题根源
data-scroll-call 事件默认会触发两次:
- 绑定元素进入视口、被添加
.is-inview类时触发 - 绑定元素离开视口、被移除
.is-inview类时触发
现有判断逻辑未区分两种触发时机,只要监听到对应call值就执行加类操作,元素离开视口时会误触发active类添加,导致导航状态错乱。
修复方法
scroll.on("call") 的回调函数自带状态参数,其中way字段会标记当前触发时机:值为enter代表元素进入视口,值为exit代表元素离开视口。仅在enter状态下执行导航状态更新即可解决误触发问题。
现有HTML结构、Locomotive Scroll初始化配置、grid布局、sticky导航相关设置均不需要改动,仅替换JS中绑定call事件的逻辑即可,原有语法、属性全部保留。
修复后完整JS代码
const navBtn1 = document.getElementById("nav-btn-1"); const navBtn2 = document.getElementById("nav-btn-2"); const navBtn3 = document.getElementById("nav-btn-3"); const navBtn4 = document.getElementById("nav-btn-4"); window.addEventListener("load", () => { const scroll = new LocomotiveScroll({ el: document.querySelector('[data-scroll-container]'), smooth: true, scrollFromAnywhere: true, multiplier: 1, getDirection: true, reloadOnContextChange: true, touchMultiplier: 3, smoothMobile: 0, smartphone: { smooth: !0, breakpoint: 766 }, tablet: { smooth: !0, breakpoint: 1010 }, }); scroll.on("call", (callValue, way) => { // 元素离开视口时直接跳过,不处理导航状态 if (way !== "enter") return; // 先清除所有导航按钮的激活状态 [navBtn1, navBtn2, navBtn3, navBtn4].forEach(btn => btn.classList.remove("active")); // 匹配当前进入视口的区块,给对应导航按钮加激活类 const navMatch = { "lst_pr": navBtn1, "old_pr": navBtn2, "arc_pr": navBtn3, "plg_pr": navBtn4 }; navMatch[callValue].classList.add("active"); }); });
补充说明
- 导航按钮元素获取逻辑移至load事件外部,避免DOM未加载完成时获取元素报错,不影响原有功能
- 修复后仅在区块滚动进入视口时更新导航状态,离开视口时不会触发状态变更,完全匹配导航高亮需求
- 未引入额外依赖,所有原有配置项保持不变
内容的提问来源于stack exchange,提问作者vizin
相关产品推荐
相关产品推荐

