使用jQuery实现点击其他按钮或外部区域关闭下拉菜单
通用下拉菜单:解决多菜单同时展开问题
你的核心问题是点击新下拉按钮时未关闭已打开的其他菜单,下面给出类封装的全局通用解决方案,完美实现「点击外部区域/其他按钮关闭已展开菜单」的需求:
修改后的完整代码
HTML(结构可复用,无需改动核心逻辑)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script> <style> .tm-dropdown { position: relative; margin: 10px; } .tm-dropdown-content { display: none; visibility: hidden; position: absolute; opacity: 0; list-style: none; padding: 8px 0; margin: 0; background: #fff; border: 1px solid #eee; transition: opacity 0.2s ease; } .tm-dropdown-content li { padding: 6px 16px; cursor: pointer; } .tm-dropdown-content li:hover { background: #f5f5f5; } .tm-dropdown.opened .tm-dropdown-content { display: block; visibility: visible; opacity: 1; } .tm-dropdown.p-start .tm-dropdown-content { right: auto; left: 0; } .tm-dropdown.p-end .tm-dropdown-content { right: 0; left: auto; } </style> <div class="tm-dropdown"> <button type="button" class="tm-button tm-button-primary-l6 tm-button-ghost text-grey-medium tm-dropdown-button"> <span>语言选择</span> </button> <ul class="tm-dropdown-content"> <li>English</li> <li>Bahasa Melayu</li> <li>中文简体</li> </ul> </div> <div class="tm-dropdown"> <button type="button" class="tm-button tm-button-primary-l6 tm-button-ghost text-grey-medium tm-dropdown-button"> <span>更多选项</span> </button> <ul class="tm-dropdown-content"> <li>设置</li> <li>帮助</li> <li>退出</li> </ul> </div>
JS(类封装实现全局通用)
class DropdownManager { constructor() { this.$dropdowns = $('.tm-dropdown'); this.bindEvents(); } bindEvents() { // 下拉按钮点击逻辑 $('.tm-dropdown-button').on('click', (e) => { e.preventDefault(); e.stopPropagation(); const $currentDropdown = $(e.target).closest('.tm-dropdown'); // 关闭其他所有下拉,再切换当前菜单状态 this.closeAllExcept($currentDropdown); $currentDropdown.toggleClass('opened'); }); // 点击页面外部关闭所有下拉 $(document).on('click touchstart', (e) => { if (!$(e.target).closest('.tm-dropdown').length) { this.closeAll(); } }); // 点击下拉内容内部不触发关闭 $('.tm-dropdown-content').on('click touchstart', (e) => { e.stopPropagation(); }); } // 关闭所有下拉菜单 closeAll() { this.$dropdowns.removeClass('opened'); } // 关闭除指定菜单外的所有下拉 closeAllExcept($exclude) { this.$dropdowns.not($exclude).removeClass('opened'); } } // 初始化全局下拉管理器,所有下拉自动生效 new DropdownManager();
关键修改说明
- 类封装逻辑:用
DropdownManager统一管理所有下拉菜单,初始化一次即可全局生效,无需重复绑定事件 - 多菜单互斥:点击按钮时先调用
closeAllExcept关闭其他已打开的下拉,再切换当前菜单的展开状态,彻底解决多菜单同时展开的问题 - 简化外部点击判断:用
closest('.tm-dropdown')直接判断点击目标是否在下拉容器内,比原代码的多层判断更简洁准确 - 内部点击不关闭:阻止下拉内容区域的点击事件冒泡,避免点击菜单选项时意外收起菜单
内容的提问来源于stack exchange,提问作者Kelvin
相关产品推荐
相关产品推荐

