如何编写函数实现多div元素的点击显示/隐藏切换?
问题分析与解决方案
核心问题
- 元素选择错误:
document.getElementsByClassName()返回的是HTMLCollection元素集合,不是单个DOM元素,直接调用x.style会无效。 - 无区分的选择器:两个菜单都用
myDIV类,函数无法判断要切换哪个元素的显示状态。 - 重复定义函数:两段代码都定义了
hideshow(),后定义的会覆盖前一个,导致逻辑混乱。 - 布局破坏风险:第二个菜单初始
display是flex,直接切换为block会打乱原有布局。
修复方案(通用可控版)
给每个菜单分配唯一ID,让按钮通过ID精准控制对应菜单,同时保留菜单原有布局的display属性:
1. 修改HTML结构(给菜单加唯一ID,按钮传递目标ID)
第一个菜单(个人资料):
<button class="navbarBTN" onclick="hideshow('profileMenu')"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" data-supported-dps="24x24" fill="currentColor" class="mercado-match" width="24" height="24" focusable="false"> <path d="M3 3h4v4H3zm7 4h4V3h-4zm7-4v4h4V3zM3 14h4v-4H3zm7 0h4v-4h-4zm7 0h4v-4h-4zM3 21h4v-4H3zm7 0h4v-4h-4zm7 0h4v-4h-4z"></path> </svg> </button> <!-- 给div加唯一ID,初始设为display:none --> <div id="profileMenu" class="flex-column bg-light rounded-3" style="position: absolute; width: 180px; font-size: smaller; margin-top: 2.5%; display: none;"> <div class="d-flex flex-column"> <ul style="margin: 0; padding: 6px; border-color:#666666; border-bottom: 2px solid;"> <p class="m-0">Costin Velicu</p> <p class="fw-light">Looking for work</p> <button type="button" class="btn btn-outline-primary rounded-5" style="width: 100%; height: 30px;"><p style="font-size: smaller;">View profile</p></button> </ul> </div> </div>
第二个菜单(消息):
<button class="navbarBTN" onclick="hideshow('messagingMenu')"> <div class="d-flex sticky-bottom bg-light" style="width: fit-content; left: 80%; position: relative;"> <i class="fa-solid fa-user-ninja" style="color: #424242; font-size: larger; margin-right: 0.5em; padding: 2px"></i> <p style="margin-right: 10em;">Messaging</p> <div class="justify-content-between"> <i class="fa-solid fa-ellipsis" style="color: #424242; margin-right: 0.5em;"></i> <i class="fa-solid fa-pen-to-square" style="color: #424242; margin-right: 0.5em;"></i> <i class="fa-solid fa-angle-up" style="color: #424242; margin-right: 0.5em;"></i> </div> </div> </button> <!-- 保留原有flex布局,加唯一ID --> <div id="messagingMenu" style="display: flex; flex-direction: column-reverse; position: relative; left: 80%;"> <div class="container d-flex flex-column bg-light-subtle" style="width: 350px; position: absolute;"> <form class="d-flex"> <input class="form-control me-1" type="search" placeholder="Search..." aria-label="Search"> </form> </div> </div>
2. 统一的hideshow函数
只需要定义一次,放在页面底部:
function hideshow(targetId) { // 通过ID获取目标元素 const menu = document.getElementById(targetId); if (!menu) return; // 元素不存在则终止 // 保存菜单初始的display值(避免切换成block破坏布局) if (!menu.dataset.originalDisplay) { menu.dataset.originalDisplay = menu.style.display || window.getComputedStyle(menu).display; } // 切换显示状态 if (menu.style.display === 'none') { menu.style.display = menu.dataset.originalDisplay; } else { menu.style.display = 'none'; } }
进阶优化(移除内联onclick,用事件委托)
如果想更规范,避免内联事件,可以用事件委托绑定按钮:
<!-- 按钮去掉onclick,加统一类和data-target属性 --> <button class="navbarBTN" data-target="profileMenu">...</button> <button class="navbarBTN" data-target="messagingMenu">...</button> <script> // 页面加载完成后绑定事件 document.addEventListener('DOMContentLoaded', function() { // 获取所有导航按钮 const buttons = document.querySelectorAll('.navbarBTN'); buttons.forEach(button => { button.addEventListener('click', function() { const targetId = this.dataset.target; const menu = document.getElementById(targetId); if (!menu) return; if (!menu.dataset.originalDisplay) { menu.dataset.originalDisplay = menu.style.display || window.getComputedStyle(menu).display; } menu.style.display = menu.style.display === 'none' ? menu.dataset.originalDisplay : 'none'; }); }); }); </script>
内容的提问来源于stack exchange,提问作者Costin
相关产品推荐
相关产品推荐

