原生js实现Tab切换+箭头滚动

一、tab切换

1,效果预览

demo需求简介:

  • js原生实现;
  • tab切换,active样式切换;
  • tab过多右侧出现箭头滚动;

2,代码实现

我们按照实现思路来实现:

(1)第一步:点击当前tab,添加active样式;

就需要给每个tab都绑定点击事件,当点击某一个tab时,需要给当前tab加上active的class名,并且去除掉其他tab兄弟们的active的class名,这样就唯我独秀啦。这其中涉及到的js语法可能会有:

添加class名:元素.classList.add("active");
去除class名:元素.classList.remove("active");

写法一:

先给每个tab-item绑定点击事件,因为item的个数不能定死,所以我们就可以循环去绑定,然后点击事件内先给每个item去掉一波active的class,然后给当前点击的这个item加上active的class不就可以了,就给他单独开小灶,你说气不气?话不多说,直接上代码:

            <ul class="tabs">
              <li class="tab-item active">tab1tab1tab1</li>
              <li class="tab-item">tab2</li>
              <li class="tab-item">tab3</li>
              <li class="tab-item">tab4</li>
              <li class="tab-item">tab5</li>
              <li class="tab-item">tab6</li>
              <li class="tab-item">tab7</li>
              <li class="tab-item">tab8</li>
            </ul>
    var tabItem = document.getElementsByClassName("tab-item");
    for (let ele = 0; ele < tabItem.length; ele++) {
      tabItem[ele].onclick = function () {
        //循环去除全部active的class
        for (let i = 0; i < tabItem.length; i++) {
          tabItem[i].classList.remove("active");
        }
        //给当前item添加active的class
        tabItem[ele].classList.add("active");
      };
    }

写法二:

或许还有另一种思路,咱也是给每个item绑定事件,也是要给当前item添加active的class,但我们可不可以去掉其他兄弟们的active,这样咱就可以不给当前的去一波了,当前的本来就没active,你还去剥削一遍,咋这么缺德捏?

但是咋获取其他的兄弟元素呢???

咱咋知道他们是我的兄弟啊?你说是就是啊?那当然得去问你爸妈不是?你爸妈告诉你他们生了几个娃,这个是老大,老二,老三....走起,说干就干:

            <ul class="tabs">
              <li class="tab-item active">tab1tab1tab1</li>
              <li class="tab-item">tab2</li>
              <li class="tab-item">tab3</li>
              <li class="tab-item">tab4</li>
              <li class="tab-item">tab5</li>
              <li class="tab-item">tab6</li>
              <li class="tab-item">tab7</li>
              <li class="tab-item">tab8</li>
            </ul>
    //获取兄弟节点
    function siblings(value, className) {
     let parent = value.parentNode;//获取父节点
      let bro = parent.childNodes;//获取子节点
      console.log("bro", bro); //打印试试
     
    }
    //循环绑定事件
    for (let ele = 0; ele < tabItem.length; ele++) {
      tabItem[ele].onclick = function () {
        tabItem[ele].classList.add("active");
        siblings(tabItem[ele], "active"); //获取兄弟节点+去除active的class
      };
    }

咋这么多玩意呀,咋还有一些text的节点呢?那是因为你问的太仔细了,七大姑八大姨都算进去了,啥表姊妹表兄弟都算上,是不是就麻烦了呢?仔细了解一下发现:

获取元素子节点的所有类型节点:元素.childNodes;(空格和换行符都会都会被默认成文本节点)
获取当前元素的子元素节点:元素.children;(不返回文本节点和属性节点)

既然如此,咱也不舍近求远了,怎么方便怎么来:

    function siblings(value, className) {
      let parent = value.parentNode;
      let bro = parent.children;
      let siblings = [];
      for (let i = 0; i < bro.length - 1; i++) {
        if (bro[i] != value) {
          siblings.push(bro[i]);
          for (const key in siblings) {
            siblings[key].classList.remove(className);
          }
        }
      }
    }
    for (let ele = 0; ele < tabItem.length; ele++) {
      tabItem[ele].onclick = function () {
        tabItem[ele].classList.add("active");
        siblings(tabItem[ele], "active");
      };
    }

通过函数调用传参的方式,把节点,和class名传进去处理,这样如果后面有需要的话,也可以调用此函数,从而减少代码的耦合性。

当然childNodes返回的结果也是可以过滤的,也能达到想要的效果:

        if (
          !(
            bro[i].nodeType == "3" &&
            bro[i].nodeName == "#text" &&
            !/\S/.test(bro[i].nodeValue)
          )
        ) {
          //正常代码
        }

(2)第二步:点击当前tab,显示相对于的tab-content内容;

很简单,也可以按照上面的思路来实现,咱通过新增一个class样式来控制tab-content的显示和隐藏即可;

.show{
    display:block;
}
.hidden{
    display:hidden;
}

写法一:

和上面实现的思路一致,全部剥削一遍,然后单独开小灶呗,开整:


                
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值