两行切换式下拉导航实现问题(非jQuery方案)
实现原生JS两行切换的下拉导航栏
我明白你遇到的问题了——当前代码只给父容器绑定了点击事件,而且仅通过rowB的显示状态来切换,完全没区分点击的是哪一行,这就导致点击Row-B时反而会把它自己隐藏,只留下Row-A。咱们来调整逻辑,用原生JS实现你要的循环切换效果:
完整代码实现
HTML
<body> <div id="content"> <div id="select"> <div id="rowA">Row-A</div> <div id="rowB">Row-B</div> </div> </div> </body>
CSS
body { margin: 0px; } #content { width: 300px; height: 300px; background: #000; display: grid; grid-template-rows: 70px 160px 70px; } #select { width: 270px; height: 90px; margin: 0 auto; color: #fff; margin-top: 10px; display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start; z-index: 2; } #rowA, #rowB { width: 270px; height: 40px; background: #000; border: #2e2e2e 1px solid; display: flex; align-items: center; z-index: 2; cursor: pointer; /* 提示这是可点击元素 */ padding-left: 10px; /* 让文字不贴边,更美观 */ }
JavaScript
const select = document.getElementById("select"); const rowA = document.getElementById("rowA"); const rowB = document.getElementById("rowB"); // 初始状态:隐藏Row-B,标记为未展开 rowB.style.display = "none"; let isExpanded = false; // 用事件委托处理点击,不用给每一行单独绑事件 select.addEventListener("click", function(e) { const target = e.target; // 过滤掉非行元素的点击(比如父容器空白处) if (target.id !== "rowA" && target.id !== "rowB") return; if (!isExpanded) { // 未展开时:点击任意行,显示两行 rowA.style.display = "flex"; rowB.style.display = "flex"; isExpanded = true; } else { // 已展开时:点击哪一行,就只保留哪一行 if (target.id === "rowA") { rowB.style.display = "none"; } else { rowA.style.display = "none"; } isExpanded = false; } });
关键逻辑说明
- 事件委托:给父容器
#select绑定点击事件,通过e.target判断用户点击的是哪一行,这样代码更简洁高效,后续新增行也不用额外加事件。 - 状态跟踪:用
isExpanded变量记录当前是否处于两行展开的状态,初始为false(仅显示Row-A)。 - 分支处理:
- 未展开状态:点击任意行都显示两行,切换到展开状态。
- 已展开状态:点击哪一行就隐藏另一行,回到单一行显示状态。
这样就能实现你要的循环效果:
- 初始:仅显示Row-A → 点击Row-A → 显示两行
- 显示两行时:点击Row-A回到仅显示Row-A;点击Row-B切换到仅显示Row-B
- 仅显示Row-B时:点击Row-B → 显示两行,重复上述流程
内容的提问来源于stack exchange,提问作者Tane
相关产品推荐
相关产品推荐

