You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何重构滑动菜单代码以避免全局变量并在函数内判断状态?

如何重构滑动菜单代码以避免全局变量?

嘿,我来帮你搞定这个全局变量的问题!你的滑动菜单逻辑其实可以很轻松地摆脱全局状态的困扰,下面给你几个实用的优化方案,咱们一步步看:

方案1:直接通过DOM元素的当前状态判断(无需额外变量)

这个思路最直接——既然你是通过修改元素的left样式来控制菜单展开/收起,那完全可以读取当前DOM的样式值来判断状态,根本不需要全局变量menuFull

修改后的代码如下:

$(document).ready(function () {
    const navButton = document.getElementById("nav_button");
    navButton.addEventListener('click', toggleMenu);
});

function toggleMenu() {
    const menuArea = document.getElementById("nav_container");
    const containerArea = document.getElementsByClassName("body_container")[0];
    
    // 直接读取菜单当前的left值判断状态
    const isMenuExpanded = menuArea.style.left === "0%";
    
    if (isMenuExpanded) {
        // 收起菜单
        menuArea.style.left = "-11.5%";
        containerArea.style.left = ""; // 重置回默认位置
        console.log("菜单已收起");
    } else {
        // 展开菜单
        menuArea.style.left = "0%";
        containerArea.style.left = "18.5%";
        console.log("菜单已展开");
    }
}

这样一来,状态完全由DOM自身的样式体现,没有全局变量,也不会出现状态被意外重置的问题。

方案2:用闭包封装状态(隐藏变量,避免全局污染)

如果你还是想保留“状态变量”的思路,但不想让它暴露在全局作用域,可以把变量和toggleMenu函数一起放进闭包里,这样变量只会在闭包内部可访问,不会污染全局。

代码示例:

$(document).ready(function () {
    // 这个变量现在只在ready的闭包内,不是全局的!
    let menuFull = false;
    
    function toggleMenu() {
        const menuArea = document.getElementById("nav_container");
        const containerArea = document.getElementsByClassName("body_container")[0];
        
        if (menuFull) {
            menuArea.style.left = "-11.5%";
            containerArea.style.left = "";
            menuFull = false;
            console.log("菜单已收起");
        } else {
            menuArea.style.left = "0%";
            containerArea.style.left = "18.5%";
            menuFull = true;
            console.log("菜单已展开");
        }
    }
    
    const navButton = document.getElementById("nav_button");
    navButton.addEventListener('click', toggleMenu);
});

这里menuFull不再是全局变量,只有toggleMenu能访问它,完美解决了全局污染的问题。

方案3:用CSS类控制状态(最推荐,符合前端最佳实践)

这个方案是我最推荐的——把样式逻辑完全放到CSS里,JS只负责添加/移除类来切换状态。这样不仅能摆脱状态变量,还能实现样式和逻辑的分离,代码更易维护,还能轻松加过渡动画提升体验。

首先修改你的CSS:

/* 默认菜单收起状态 */
#nav_container {
    left: -11.5%;
    transition: left 0.3s ease; /* 加上过渡动画,菜单滑动更流畅 */
}
/* 菜单展开状态的类 */
#nav_container.menu-open {
    left: 0%;
}

/* 默认内容容器位置 */
.body_container {
    left: 0%;
    transition: left 0.3s ease;
}
/* 菜单展开时内容容器的位置类 */
.body_container.menu-shifted {
    left: 18.5%;
}

然后修改JS代码:

$(document).ready(function () {
    const navButton = document.getElementById("nav_button");
    const menuArea = document.getElementById("nav_container");
    const containerArea = document.getElementsByClassName("body_container")[0];
    
    function toggleMenu() {
        // 通过检查类是否存在来判断状态
        const isMenuOpen = menuArea.classList.contains('menu-open');
        
        if (isMenuOpen) {
            // 移除展开类,回到收起状态
            menuArea.classList.remove('menu-open');
            containerArea.classList.remove('menu-shifted');
            console.log("菜单已收起");
        } else {
            // 添加展开类,切换到展开状态
            menuArea.classList.add('menu-open');
            containerArea.classList.add('menu-shifted');
            console.log("菜单已展开");
        }
    }
    
    navButton.addEventListener('click', toggleMenu);
});

这个方案的优势在于:样式都在CSS里管理,JS只负责逻辑控制,状态由类的存在与否体现,完全不需要任何状态变量,代码也更干净易读。


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

火山引擎 最新活动