jQuery移动端菜单toggle第二次点击无法关闭问题排查
问题根因
问题和"jQuery仅记录页面加载初始属性状态"的猜测无关,是代码中两处错误直接导致else分支永远不执行:
- 核心语法错误:判断条件写为
if (visibility = true),单等号=是赋值操作而非相等比较,该表达式永远返回true,逻辑判断完全失效,每次点击都会强制走设置可见的分支。 - jQuery API混用错误:jQuery的
.data()方法首次读取DOM上的data-*属性后,会将值存入内部缓存,后续如果用.attr()修改DOM上的同名data属性,不会同步更新.data()读取的缓存值,即便修正判断符号,读写方法不统一也会出现状态不同步问题。 - 额外隐患:
document.getElementsByClassName返回的是类数组格式的元素集合,并非单个DOM节点,直接包装为jQuery对象在多元素场景下易出现状态读写混乱。
修复方案
统一元素获取方式、修正判断符号、保证data属性读写方法一致即可,修复后的代码如下:
jQuery(document).ready(function($) { // 直接通过jQuery选择器获取目标元素,避免拿到元素集合 const $primaryNav = $('.header'); const $navToggle = $('.mobile-nav-toggle'); $navToggle.on('click', function() { // 统一使用.data()方法读写data属性,不与.attr()混用 const visibility = $primaryNav.data('visible'); if (visibility) { // 当前为展开状态,执行关闭逻辑 $primaryNav.data("visible", false); $navToggle.attr("aria-expanded", false); } else { // 当前为关闭状态,执行展开逻辑 $primaryNav.data("visible", true); $navToggle.attr("aria-expanded", true); } }) });
如果需要让CSS通过属性选择器匹配菜单状态(比如用
[data-visible="true"]写展开样式),可以统一使用.attr()完成data属性读写,避免DOM属性和jQuery缓存不同步,示例如下:jQuery(document).ready(function($) { const $primaryNav = $('.header'); const $navToggle = $('.mobile-nav-toggle'); // 初始给导航设置默认状态,和aria-expanded初始值保持一致 $primaryNav.attr('data-visible', 'false'); $navToggle.on('click', function() { const isVisible = $primaryNav.attr('data-visible') === 'true'; if (isVisible) { $primaryNav.attr("data-visible", "false"); $navToggle.attr("aria-expanded", "false"); } else { $primaryNav.attr("data-visible", "true"); $navToggle.attr("aria-expanded", "true"); } }) });
内容的提问来源于stack exchange,提问作者BorderlineVis
相关产品推荐
相关产品推荐

