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

移动端菜单淡入淡出切换异常求助:第三次点击双元素消失

问题分析与修复方案

问题根源

你遇到的问题核心是事件监听累加:每次点击隐藏菜单时,代码都会给mobileMenu新增一个animationend事件监听,但没有清理之前的监听。第二次点击后,这个监听已经存在;第三次点击显示菜单时,fadeIn动画结束后会触发之前遗留的animationend回调,把mobileMenu设为none;同时显示菜单的逻辑里已经将mainBody设为none,最终导致两个元素都消失。

修复代码(基础版)

// 提前缓存DOM元素,避免重复查询DOM提升性能
const mobileMenu = document.getElementById("mobileMenu");
const mainBody = document.getElementById("mainBody");

function mobileMenuToggle(){
    if (mobileMenu.style.display === "none"){
        mobileMenu.style.animationName = "fadeIn";
        mobileMenu.style.display = "block";
        mainBody.style.display = "none";
    } else if(mobileMenu.style.display === "block"){
        mainBody.style.display = "block";
        mobileMenu.style.animationName = "fadeOut";
        
        // 使用{ once: true }确保回调仅执行一次,不会累加监听
        mobileMenu.addEventListener("animationend", () => {
            mobileMenu.style.display = "none";
        }, { once: true });
    }
}

优化方案(CSS类管理)

更推荐用CSS类来控制状态和动画,减少直接操作DOM样式,代码更易维护:

CSS 部分

/* 初始状态 */
#mobileMenu {
    display: none;
    animation-duration: 0.3s; /* 统一动画时长 */
}
#mainBody.hidden {
    display: none;
}

/* 动画类 */
#mobileMenu.fade-in {
    animation-name: fadeIn;
    display: block;
}
#mobileMenu.fade-out {
    animation-name: fadeOut;
    display: block;
}

/* 定义动画 */
@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}
@keyframes fadeOut {
    from { opacity: 1; }
    to { opacity: 0; }
}

JS 部分

const mobileMenu = document.getElementById("mobileMenu");
const mainBody = document.getElementById("mainBody");

function mobileMenuToggle(){
    // 判断菜单当前状态
    const isMenuHidden = mobileMenu.style.display === "none" || !mobileMenu.classList.contains("fade-in");
    
    if (isMenuHidden) {
        // 显示菜单:移除淡出类,添加淡入类
        mobileMenu.classList.remove("fade-out");
        mobileMenu.classList.add("fade-in");
        mainBody.classList.add("hidden");
    } else {
        // 隐藏菜单:移除淡入类,添加淡出类
        mobileMenu.classList.remove("fade-in");
        mobileMenu.classList.add("fade-out");
        mainBody.classList.remove("hidden");
        
        // 动画结束后重置菜单状态
        mobileMenu.addEventListener("animationend", () => {
            mobileMenu.classList.remove("fade-out");
            mobileMenu.style.display = "none";
        }, { once: true });
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:57:16