关闭MDCSimpleMenu菜单后需点击两次才能重新打开的问题排查求助
问题分析与解决方案
这是典型的事件冒泡导致的两次点击异常,我来帮你拆解原因和修复方法:
问题根源
当你点击菜单触发按钮(.js-dropdown-toggle)时,事件会先执行按钮的click回调,把mdcMenu.open设为true(打开菜单),但这个事件会继续向上冒泡到body上,触发你绑定的closeDropdownMenu方法——相当于第一次点击其实是「打开→立刻关闭」,所以你需要再点一次才能真正触发打开操作。
修复方案(两种可选)
方案1:在按钮点击事件中阻止冒泡
修改按钮的click监听,添加event.stopPropagation(),阻止事件冒泡到body,避免触发关闭逻辑:
menuToggleEL.addEventListener('click', (event) => { event.stopPropagation(); // 阻止事件向上传递到body mdcMenu.open = !mdcMenu.open; });
方案2:优化body的点击事件,排除菜单相关元素
在closeDropdownMenu里判断点击目标是不是菜单或按钮本身,如果是就跳过关闭逻辑:
closeDropdownMenu(event) { const menuEl = document.querySelector('.mdc-simple-menu'); const toggleEl = document.querySelector('.js-dropdown-toggle'); // 如果点击的是菜单或按钮内部,不执行关闭 if (menuEl.contains(event.target) || toggleEl.contains(event.target)) { return; } // 更推荐用组件实例的属性控制,而非手动修改class if (mdcMenu.open) { mdcMenu.open = false; } } // 绑定事件时要传递event参数 document.querySelector('body').addEventListener('click', (event) => this.closeDropdownMenu(event) );
额外提醒:MDCSimpleMenu本身提供了open属性来控制显示隐藏,尽量直接操作实例的mdcMenu.open,而不是手动添加/移除class,这样能保证组件内部状态和UI完全同步。
内容的提问来源于stack exchange,提问作者London804




