You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:01:07