JavaScript实战篇: 选项卡功能

原生 JavaScript 实现选项卡功能

本文源自JavaScript课时0407

一、HTML 结构

激活样式默认锁定在第一个元素上
导航栏和内容进行自定义属性绑定

<div class="tabs">
  <!-- 主导航 -->
  <ul class="tab">
    <li class="active" data-index="1">国内</li>
    <li data-index="2">国际</li>
    <li data-index="3">省内</li>
  </ul>

  <!-- 与导航标签对应的详情列表 -->
  <ul data-index="1" class="item active">
    <li><a href="">国内新闻</a></li>
    <li><a href="">国内新闻</a></li>
    <li><a href="">国内新闻</a></li>
    <li><a href="">国内新闻</a></li>
  </ul>

  <ul data-index="2" class="item">
    <li><a href="">国际新闻</a></li>
    <li><a href="">国际新闻</a></li>
    <li><a href="">国际新闻</a></li>
    <li><a href="">国际新闻</a></li>
  </ul>

  <ul data-index="3" class="item">
    <li><a href="">省内新闻</a></li>
    <li><a href="">省内新闻</a></li>
    <li><a href="">省内新闻</a></li>
    <li><a href="">省内新闻</a></li>
  </ul>
</div>

二、CSS 样式表

display: block;表示样式激活
display: none;默认隐藏内容

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

li {
  list-style: none;
}

.tabs {
  /* border: 1px solid #000; */

  width: 600px;

  margin: 0 auto;
}

.tabs > .tab {
  /* border: 1px solid #000; */

  width: 600px;

  display: flex;
  flex-flow: row nowrap;
  justify-content: center;
  align-items: center;

  background-color: bisque;
  border-radius: 20px;
}

.tabs > .tab:hover {
  cursor: pointer;
}

.tabs > .tab > li {
  width: 200px;

  flex: 1;

  text-align: center;
}

.tabs > .tab > .active {
  background-color: #ccc;

  border-radius: 20px;
}

.tabs > .item {
  /* 默认只有active值能出现 */
  display: none;

  text-align: start;
  text-indent: 20px;
  margin: 10px 0;
  padding: 10px 0;
}

.tabs > .item > li {
  height: 20px;
}

.tabs > .item > li > a {
  letter-spacing: 2px;
}

.tabs > .active {
  /* 显示 */
  display: block;

  background-color: #ccc;
  border-radius: 5px;
}

三、JavaScript 脚本

(一)、获取 dom 元素

// 获取 导航 元素,点击事件 拿到 HTML 标签
const tab = document.querySelector(".tab");
console.log(tab);

// 通过父元素往下拿子元素
// 拿到导航栏的所有值组成的类数组
console.log(tab.children); //打印:HTMLCollection(3) [li.active, li, li]
console.log([...tab.children]); //打印:[li.active, li, li] 数组

// 也可以直接拿到子元素,但是如果父元素有点击的事件,优先拿父元素,然后再通过父元素拿到子元素的内容,岂不美哉!
// const tabs = document.querySelectorAll(".tab > li");
// console.log(tabs); // NodeList(3) [li.active, li, li]

// 获取 新闻 ,拿所有元素,方便转变 class 值
const items = document.querySelectorAll(".item");
console.log(items);

(二)、为主导航栏添加点击事件

tab.onclick = (ev) => {
  // 测试代码
  // console.log('object');

  // console.log([...tab.children]); //打印:[li.active, li, li] 数组

  // 一、消除 激活 样式
  [...tab.children].forEach((item) => item.classList.remove("active"));
  ev.target.classList.add("active");

  // 二、根据元素的点击值来添加激活样式
  console.log(ev.target.dataset.index); //拿到自定义属性 data-index 的值

  // 移除内容的 激活 样式
  items.forEach((item) => item.classList.remove("active"));

  // 弹出 items 元素集合中的 data-index 值等于 ev.target.dataset.index 的值,并单独为他添加 激活 样式

  // 这里需要使用数组函数来判断data-index的值一样返回的数组值
  // filter 弹出返回 true 的数组
  [...items]
    .filter((item) => item.dataset.index === ev.target.dataset.index)[0]
    .classList.add("active");
};

本文到此结束啦,如果对你有帮助,记得留下你的点赞喔!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小趴菜RQS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值