如何重构滑动菜单代码以避免全局变量并在函数内判断状态?
如何重构滑动菜单代码以避免全局变量?
嘿,我来帮你搞定这个全局变量的问题!你的滑动菜单逻辑其实可以很轻松地摆脱全局状态的困扰,下面给你几个实用的优化方案,咱们一步步看:
方案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




