如何通用化JS代码,使其适配同类型的所有按钮?
如何将Edit按钮下拉菜单的JS代码通用化,无需依赖ID适配所有条目
步骤1:优化HTML结构
先给所有Edit按钮添加统一的类名(比如edit-toggle),同时修正HTML规范问题(li必须是ul的直接子元素,不能被a标签包裹):
<button class="edit-toggle" aria-expanded="false">Edit</button> <ul class="list-edit text-black" style="display: none; margin-top: 10px;"> <li class="list-items-edit"> <a href="#">Edit</a> </li> <li class="list-items-edit"> <a href="#" class="popup-with-zoom-anim">Unpublish</a> </li> <li class="list-items-edit"> <a href="#" class="popup-with-zoom-anim">Delete</a> </li> </ul>
步骤2:通用化JS代码
通过事件委托和DOM关系关联实现无ID依赖的逻辑,同时支持动态添加的条目:
// 封装复用的展开/收起函数 function showMenu(toggleBtn, menuContent) { toggleBtn.setAttribute('aria-expanded', true); menuContent.style.display = "block"; } function hideMenu(toggleBtn, menuContent) { toggleBtn.setAttribute('aria-expanded', false); menuContent.style.display = "none"; } // 跟踪当前激活的菜单,确保同一时间只展开一个 let activeMenu = null; // 事件委托处理按钮点击 document.addEventListener('click', (event) => { const toggleBtn = event.target.closest('.edit-toggle'); if (toggleBtn) { event.stopPropagation(); // 通过相邻兄弟元素获取对应菜单(前提是菜单紧跟在按钮之后) const menuContent = toggleBtn.nextElementSibling; const isExpanded = JSON.parse(toggleBtn.getAttribute('aria-expanded')); // 先关闭之前打开的其他菜单 if (activeMenu && activeMenu.content !== menuContent) { hideMenu(activeMenu.btn, activeMenu.content); } // 切换当前菜单状态 if (isExpanded) { hideMenu(toggleBtn, menuContent); activeMenu = null; } else { showMenu(toggleBtn, menuContent); activeMenu = { btn: toggleBtn, content: menuContent }; } } else { // 点击页面其他区域,关闭所有展开的菜单 if (activeMenu) { hideMenu(activeMenu.btn, activeMenu.content); activeMenu = null; } } }); // 处理外部聚焦事件,关闭菜单 document.addEventListener('focusin', (event) => { if (activeMenu && !activeMenu.content.contains(event.target) && event.target !== activeMenu.btn) { hideMenu(activeMenu.btn, activeMenu.content); activeMenu = null; } });
核心逻辑说明
- 事件委托:通过监听
document的点击事件,避免给每个按钮单独绑定事件,同时支持动态新增的条目。 - DOM关系关联:用
nextElementSibling直接获取按钮对应的下拉菜单,无需依赖ID;如果菜单和按钮的结构关系改变,也可以给按钮添加data-target属性指定选择器,比如<button class="edit-toggle" data-target="#menu1">,再用document.querySelector(toggleBtn.dataset.target)获取菜单。 - 状态跟踪:通过
activeMenu变量记录当前展开的菜单,确保同一时间只有一个菜单处于展开状态,提升用户体验。
内容的提问来源于stack exchange,提问作者c.dasa
相关产品推荐
相关产品推荐

