You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过点击对应导航按钮切换Div内容?

问题描述

我需要实现一个网站模块:点击导航按钮后,下方对应的内容区块切换显示。目前已完成部分开发,但存在两个问题:

  1. 切换激活状态时,必须先点击Div1的导航,否则Div1和Div2的激活状态无法正常切换;
  2. 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);
  });
});

代码亮点说明

  1. 语义化关联:使用data-target属性将导航和内容区块绑定,无需硬编码ID,后续添加更多tab时只需复制结构即可;
  2. CSS控制显示:通过active类统一管理导航样式和内容显示,实现CSS与JS职责分离,避免直接操作内联样式;
  3. 通用逻辑复用:编写单个switchTab函数处理所有切换逻辑,消除代码冗余;
  4. 初始化简洁:直接在HTML中给默认激活的元素添加active类,无需额外JS初始化代码;
  5. 原生API规范:使用querySelectorAll批量获取元素,循环绑定事件,符合原生JavaScript的规范写法,适合新手学习。

内容的提问来源于stack exchange,提问作者Alessandro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 07:45:00