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

使用mmenuJS插件时固定滚动头部出现异常问题

问题原因及解决方案

核心原因

  1. 高度计算时机错误:你在DOMContentLoaded触发时先获取了.header__top的高度headerFixedPosition,随后才初始化mmenu。但mmenu初始化过程中会修改DOM结构(比如移动菜单元素、添加offcanvas容器),导致页面布局发生变化,初始获取的header高度和实际渲染后的高度不符,滚动时的判断条件window.scrollY > headerFixedPosition无法满足,因此不会添加fixed类。

  2. 堆叠上下文冲突:mmenu的offcanvas模式会给页面内容容器添加transform属性(如translate3d),这会创建新的堆叠上下文,导致设置了position: fixed的header不再相对于视口定位,而是相对于这个带transform的容器,滚动时无法固定显示。而打开关闭菜单后,mmenu会移除或调整该transform属性,fixed定位恢复正常。

解决方案

方案1:延迟计算header高度

将header高度的计算移到mmenu初始化完成之后,确保获取的是布局稳定后的高度:

window.addEventListener('DOMContentLoaded', () => {
    // 先初始化mmenu
    const menu = new Mmenu("#mobilemenu", {
        offCanvas: {
            position: 'right'
        },
        slidingSubmenus: false
    });
    const api = menu.API;
    document.querySelector("#openmenu").addEventListener("click", () => {
        api.open();
    });

    // 初始化完成后再计算header高度
    const headerFixedPosition = document.querySelector('.header__top').clientHeight;
    window.addEventListener('scroll', () => {
        if (window.scrollY > headerFixedPosition) {
            document.querySelector('.header__top').classList.add('fixed');
            document.body.style.paddingTop = `${headerFixedPosition}px`;

            if (window.scrollY > (headerFixedPosition + 50)) {
                document.querySelector('.header__top').classList.add('fade-in')
            } else {
                document.querySelector('.header__top').classList.remove('fade-in')
            }
        } else {
            document.querySelector('.header__top').classList.remove('fixed')
            document.body.style.paddingTop = 0;
        }
    });
})

方案2:禁用mmenu的页面transform

修改mmenu配置,关闭页面容器的transform属性,避免创建堆叠上下文影响fixed定位:

const menu = new Mmenu("#mobilemenu", {
    offCanvas: {
        position: 'right',
        page: {
            css: {
                transform: false
            }
        }
    },
    slidingSubmenus: false
});

方案3:滚动时动态计算高度

将header高度的计算移到scroll事件内部,每次滚动都重新获取最新高度,避免布局变化导致的数值过时:

window.addEventListener('scroll', () => {
    const headerFixedPosition = document.querySelector('.header__top').clientHeight;
    if (window.scrollY > headerFixedPosition) {
        document.querySelector('.header__top').classList.add('fixed');
        document.body.style.paddingTop = `${headerFixedPosition}px`;

        if (window.scrollY > (headerFixedPosition + 50)) {
            document.querySelector('.header__top').classList.add('fade-in')
        } else {
            document.querySelector('.header__top').classList.remove('fade-in')
        }
    } else {
        document.querySelector('.header__top').classList.remove('fixed')
        document.body.style.paddingTop = 0;
    }
});

内容的提问来源于stack exchange,提问作者pkberlin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 06:20:27