如何通过点击对应导航按钮切换Div内容?
问题描述
我需要实现一个网站模块:点击导航按钮后,下方对应的内容区块切换显示。目前已完成部分开发,但存在两个问题:
- 切换激活状态时,必须先点击Div1的导航,否则Div1和Div2的激活状态无法正常切换;
- JavaScript代码过于冗余。
需求细节:
- 页面加载完成时,第一个导航处于激活状态,且对应内容区块默认显示;
- 点击Div1或Div2的导航,能同步切换对应内容区块的显示状态和导航的激活样式;
- 希望使用无jQuery的原生JavaScript实现,我是JS新手,想借此学习原生写法。
解决方案
核心问题分析
原代码的问题在于:
- 未声明
div1Link变量就直接使用,依赖浏览器的全局ID自动绑定行为,不符合规范; - 通过CSS设置的
display: none无法通过element.style.display获取,导致点击Div2时的判断逻辑出错; - 每个导航单独编写点击事件,代码重复度高。
优化实现方案
下面是重构后的简洁实现,遵循原生JS最佳实践,同时解决所有问题:
优化后的HTML
<html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>Tab Switch Demo</title> </head> <body> <div class="inline-grid"> <div class="inline-grid-item"> <!-- 初始添加active类,通过data-target关联对应内容ID --> <p class="client-grid-link active" data-target="div1-content">div1</p> </div> <div class="inline-grid-item"> <p class="client-grid-link" data-target="div2-content">div2</p> </div> </div> <div class="add-section active" id="div1-content"> <p class="add-paragraph">This is div 1.</p> </div> <div class="add-section" id="div2-content"> <p class="add-paragraph">Div2 is different from div1</p> </div> </body> </html>
优化后的CSS
.inline-grid { display: grid; grid-template-columns: 1fr 1fr; margin: 0 auto; } .inline-grid-item { display: flex; align-items: center; justify-content: center; } .client-grid-link { border-bottom: 0.18rem solid transparent; cursor: pointer; transition: all 0.2s ease; } /* 统一处理导航的hover和active样式,避免重复ID选择器 */ .client-grid-link:nth-child(1):hover, .client-grid-link.active:nth-child(1) { border-bottom-color: #970fc2; color: #970fc2; } .client-grid-link:nth-child(2):hover, .client-grid-link.active:nth-child(2) { border-bottom-color: #52b54b; color: #52b54b; } /* 默认隐藏所有内容区块,通过active类控制显示 */ .add-section { display: none; } .add-section.active { display: block; }
优化后的JavaScript
// 批量获取所有导航链接和内容区块 const tabLinks = document.querySelectorAll('.client-grid-link'); const contentSections = document.querySelectorAll('.add-section'); // 通用切换函数,处理所有导航的切换逻辑 function switchTab(targetContentId) { // 移除所有导航的激活状态 tabLinks.forEach(link => link.classList.remove('active')); // 移除所有内容区块的激活状态 contentSections.forEach(section => section.classList.remove('active')); // 给当前点击的导航添加激活状态 event.target.classList.add('active'); // 显示对应的内容区块 document.getElementById(targetContentId).classList.add('active'); } // 给每个导航绑定点击事件 tabLinks.forEach(link => { link.addEventListener('click', function() { // 从data-target属性获取对应内容的ID switchTab(this.dataset.target); }); });
代码亮点说明
- 语义化关联:使用
data-target属性将导航和内容区块绑定,无需硬编码ID,后续添加更多tab时只需复制结构即可; - CSS控制显示:通过
active类统一管理导航样式和内容显示,实现CSS与JS职责分离,避免直接操作内联样式; - 通用逻辑复用:编写单个
switchTab函数处理所有切换逻辑,消除代码冗余; - 初始化简洁:直接在HTML中给默认激活的元素添加
active类,无需额外JS初始化代码; - 原生API规范:使用
querySelectorAll批量获取元素,循环绑定事件,符合原生JavaScript的规范写法,适合新手学习。
内容的提问来源于stack exchange,提问作者Alessandro
相关产品推荐
相关产品推荐

