实现tab选项卡的几种方式

Tab栏切换主要分为2大模块:

上面的模块选项卡:当点击某一个时,当前的这个底色会变色,其余不变(排他思想) 修改类名的方式

下面的模块内容:跟随上面的选项卡变化,因此下面模块变化需要写到上面模块选项卡的点击事件里

       难点在于如何实现点击上面选项卡模块,下面模块显示其对应的内容,这里可以利用 自定义属性 的方式进行(当然这只是其中一种思路):给每个选项卡通过自定义属性设置其索引号,可以通过 getAttribute 得到当前点击的这个选项卡的索引号,让相应的内容模块显示出来即可

 

方式1:

<!-- 选项卡部分 -->
<div id="tab">
  <!-- 头部区域 -->
  <div class="tab-header" id="tab-header">
    <ul>
      <li class="selected">公告</li>
      <li>规则</li>
      <li>论坛</li>
      <li>安全</li>
      <li>公益</li>
    </ul>
  </div>

  <!-- 身体部分 -->
  <div id="tab-content">
    <!-- 第一部分 -->
    <div class="dom" style="display: block;">
      <ul>
        <li>
          <a href="#">数据七夕:金牛爱送玫瑰</a>
        </li>
        <li>
          <a href="#">阿里打造“互联网监管”</a>
        </li>
        <li>
          <a href="#">10万家店60万新品</a>
        </li>
        <li>
          <a href="#">全球最大网上时装周</a>
        </li>
      </ul>
    </div>

    <!-- 第二部分 -->
    <div class="dom">
      <ul>
        <li>
          <a href="#">“全额返现”要管控啦</a>
        </li>
        <li>
          <a href="#">淘宝新规发布汇总(7月)</a>
        </li>
        <li>
          <a href="#">炒信规则调整意见反馈</a>
        </li>
        <li>
          <a href="#">质量相关规则近期变更</a>
        </li>
      </ul>
    </div>

  <!-- 第三部分 -->
  <div class="dom">
    <ul>
      <li>
        <a href="#">阿里建商家全链路服务</a>
      </li>
      <li>
        <a href="#">个性化消费时代来临</a>
      </li>
      <li>
        <a href="#">跨境贸易是中小企业机</a>
      </li>
      <li>
        <a href="#">美妆行业虚假信息管控</a>
      </li>
    </ul>
  </div>

  <!-- 第四部分 -->
  <div class="dom">
    <ul>
      <li>
        <a href="#">接次文件,毁了一家店</a>
      </li>
      <li>
        <a href="#">账号安全神器</a>
      </li>
      <li>
        <a href="#">最新版微信上线</a>
      </li>
      <li>
        <a href="#">信用卡中的小套路</a>
      </li>
    </ul>
  </div>

  <!-- 第五部分 -->
  <div class="dom">
    <ul>
      <li>
        <a href="#">为了公益hi起来</a>
      </li>
      <li>
        <a href="#">水滴筹</a>
      </li>
      <li>
        <a href="#">公益图书--我们来啦</a>
      </li>
    </ul>
  </div>

  </div>
</div>
a {
  text-decoration: none;
  color: #000;
}

body {
  margin: 80px;
}

#tab {
  border: 1px solid #ddd;
  width: 498px;
  height: 130px;
}

/* 头部区域 */
#tab-header {
  height: 38px;
  background-color: #f7f7f7;
  position: relative;
}


.tab-header ul {
  width: 501px;
  position: absolute;
  /* 设置竖线合并 */
  left: -1px;
}


.tab-header ul li {
  float: left;
  width: 98px;
  height: 38px;
  line-height: 38px;
  text-align: center;
  padding: 0px 1px;
  border-bottom: 1px solid #ddd;
}

.tab-header ul li:hover {
  cursor: pointer;
  font-weight: 700;
  color: skyblue;
}


/* 内容区域 */
#tab-content ul {
  margin-top: 10px;
}


#tab-content ul  li {
  float: left;
  width: 220px;
  margin: 10px;
}

#tab-content ul  li a:hover {
  color: orangered;
}

#tab-content .dom {
  display: none;
}

1.1 原生js实现:

//获得元素
var lis = document.querySelectorAll('#tab-header li');
var content = document.querySelectorAll('#tab-content .dom');

//遍历li
for (var i = 0; i < lis.length; i++) {

  var li = lis[i];

  //绑定id(
  //绑定(负责选中的)
  li.id = i;

  // 3.添加事件
  li.addEventListener('mousemove', function () {
      // 添加样式之前清除有li的样式
      for (var j = 0; j < lis.length; j++) {
        //清除class
        lis[j].className = '';

      // 显示内容之前,把所有显示的隐藏
      content[j].style.display = 'none';
      }

      //设置className
      this.className = 'selected';

      //设置内容显示
      content[this.id].style.display = 'block';
  });

}


1.2 闭包实现:

//获得元素
var lis = document.querySelectorAll('#tab-header li');
var content = document.querySelectorAll('#tab-content .dom');



// 遍历1级菜单里的li元素
for (var i = 0; i < lis.length; i++) {

      // onmouseenter、onmousemove与mousemove的区别:
      // 其支持冒泡,所以当鼠标移入或鼠标移入其子元素的时候都会触发相关事件
      // 其不支持冒泡,所以当鼠标移入这个元素本身的时候会触发相关事件
      // 不支持冒泡事件,当鼠标在元素上移动的时候会触发相关事件
      lis[i].onmousemove = ( function (i) {

          return function () {
              for (var j = 0; j < lis.length; j++) {
                  content[j].style.display = 'none';
                  lis[j].style.backgroundColor = '#795da3';
              }
              content[i].style.display = 'block';
              lis[i].style.backgroundColor = 'orange';
          }
      })(i)
  }


1.3 jQuery实现:

function $(id) {
  return typeof id === 'string' ? document.getElementById(id) : id;
}

window.onload = function() {
  //获取头部所有的li标签和中间内容标签
  var lis = $('tab-header').getElementsByTagName('li');
  var content = $('tab-content').getElementsByClassName('dom');

  //打印是否获取了相应的内容
  // console.log(lis,content);

  //判断
  if(lis.length != content.length) return;

  //遍历监听鼠标在头部上的移动
  for(var i = 0; i < lis.length; i++){
    //移除淡出的li标签
    var li = lis[i];

    //绑定id(
    //绑定(负责选中的)
    li.id = i;

    //监听鼠标在li上的移动
    li.onmousemove = function() {
      for(var j = 0; j < lis.length; j++){
        //清除class
        lis[j].className = '';

        //让所有的内容隐藏
        content[j].style.display = 'none';
      }
      //设置className
      this.className = 'selected';

      //设置内容显示
      content[this.id].style.display = 'block';
    };
  }
};


方式2:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tab栏</title>
    <link rel="stylesheet" href="./css/reset.css">
    <link rel="stylesheet" href="./css/index.min.css">
</head>
<body>
    <div class="tab">
        <div class="tab_list">
            <ul>
                <li class="current">商品介绍</li>
                <li>规格与包装</li>
                <li>售后保障</li>
                <li>商品评价(500000)</li>
                <li>手机社区</li>
            </ul>
        </div>
        <div class="tab_icon">
            <div class="item" style="display: block;">
                商品介绍模块内容
            </div>
            <div class="item">
                规格与包装模块内容
            </div>
            <div class="item">
                售后保障模块内容
            </div>
            <div class="item">
                商品评价模块内容
            </div>
            <div class="item">
                手机社区模块内容
            </div>
        </div>
    </div>

    <script src="./js/index.js"></script>
</body>
</html>
.tab {
  width: 978px;
  margin: 100px auto;
}

.tab .tab_list {
  height: 39px;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

.tab .tab_list ul {
  display: flex;
  justify-content: space-around;
}

.tab .tab_list ul li {
  line-height: 39px;
  cursor: pointer;
  padding: 0 15px;
}

.tab .tab_list ul li.current {
  background-color: #c81623;
  color: #fff;
}

.tab .tab_icon .item {
  padding: 20px;
  display: none;
}

reset.css 略

// 1. 获取元素
const tab_list = document.querySelector(".tab_list");
const lis = tab_list.querySelectorAll("li");
const items = document.querySelectorAll(".item");
for(let i = 0; i < lis.length; i++){
    // 给上面的选项卡设置索引号
    lis[i].setAttribute('data-id', i);
    lis[i].onclick = function(){
        // 排他思想:干掉所有人,其余li清除  class 这个类
        for(let j = 0; j < lis.length; j++){
            lis[j].className = '';
        }
        // 留下自己
        this.className = 'current';
        // 显示内容
        let id = this.getAttribute('data-id');
        // 干掉其他,显示自己
        for(let k = 0; k < items.length; k++){
            items[k].style.display = "none";
        }
        items[id].style.display = "block";
    };
}


 

封装 Tab 栏:

        * {
            margin: 0;
            padding: 0;
        }
        
        #tab {
            width: 400px;
            height: 300px;
            border: 1px solid #000;
            margin: 100px auto;
        }
        
        #tab_top {
            list-style: none;
            width: 100%;
            height: 50px;
            line-height: 50px;
            text-align: center;
            display: flex;
            justify-content: space-between;
        }
        
        #tab_top>li {
            width: 80px;
            height: 100%;
            background: skyblue;
            border-right: 1px solid #ccc;
        }
        
        #tab_top>li:last-child {
            border-right: none;
        }
        
        #tab_bottom {
            width: 100%;
            height: 250px;
        }
        
        #tab_bottom>.tab-content {
            width: 100%;
            height: 100%;
            display: none;
        }
        
        .selected {
            background: red !important;
        }
    <div id="tab">
        <ul id="tab_top">
            <li class="tab-item selected">新闻</li>
            <li class="tab-item">视频</li>
            <li class="tab-item">音乐</li>
            <li class="tab-item">军事</li>
            <li class="tab-item">财经</li>
        </ul>
        <div id="tab_bottom">
            <div class="tab-content">新闻的内容</div>
            <div class="tab-content">视频的内容</div>
            <div class="tab-content">音乐的内容</div>
            <div class="tab-content">军事的内容</div>
            <div class="tab-content">财经的内容</div>
        </div>
    </div>
        class Tab {
            constructor() {
                this.oTabItems = document.querySelectorAll(".tab-item");
                this.oTabContents = document.querySelectorAll(".tab-content");
                this.oTabContents[0].style.display = "block";
                this.previosIndex = 0;
            }
            addClickEvent() {
                for (let i = 0; i < this.oTabItems.length; i++) {
                    //取出每一个li
                    const tabItem = this.oTabItems[i];

                    tabItem.onclick = () => {
                        this._change(i);
                    };
                }
            }

            addMoveEvent() {
                for (let i = 0; i < this.oTabItems.length; i++) {
                    //取出每一个li
                    const tabItem = this.oTabItems[i];

                    tabItem.onmousemove = () => {
                        this._change(i);
                    };
                }
            }

            /*如果在方法名称前面加上_, 代表告诉其他的程序员这个是一个私有的方法, 不要调用
             * 注意点: 仅仅是告诉别人这个是一个私有的方法, 并不是真正的是一个私有的方法*/
            _change(i) {
                //1.排他操作
                //1.1拿到上一次选中的选项卡并删除selected类
                const preTabItem = this.oTabItems[this.previosIndex];
                preTabItem.className = preTabItem.className.replace("selected", "");

                //1.2拿到上一次选中的内容并清空
                const preTabContent = this.oTabContents[this.previosIndex];
                preTabContent.style.display = "none";

                //2.设置当前样式
                const curTabItem = this.oTabItems[i];
                curTabItem.className = curTabItem.className + " selected";
                const curTabContent = this.oTabContents[i];
                curTabContent.style.display = "block";

                //3.保存当前索引
                this.previosIndex = i;
            }
        }

        const tab = new Tab();
        tab.addClickEvent();
        // tab.addMoveEvent();

感兴趣的小伙伴可以动手试试喔!

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小白小白从不日白

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

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

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

打赏作者

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

抵扣说明:

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

余额充值