联合创作人招募中!
微信联系:yulone

新手向:三种方法实现页面标签切换展示(JavaScript、CSS、jQuery)

在做UI的时候非常常用的一个功能就是tab标签切换,这已经成为了现代UI几乎必备的功能,这个教程比较新手向,主要是记录一下tab标签内容切换的实现的两种方法:一种是传统的利用jQuery(或其他框架)实现,另一种是纯CSS实现。[5.24]更新了一种原生JavaScript的方法,以供一些jQuery有冲突的同学使用。

这三种方法使用的场景不太一样,因此不能简单地判定它们的好坏,具体的下面会说。

方法一:jQuery+CSS实现

js实现比较简单,以左右布局为例,原理是通过判断mouseover()的行为,给制定的dom加上一个class,如“on”,然后对“on”这个class在CSS中显示出来:display:block;。具体的实例代码如下:

HTML代码:

<div class="navi-section">
  <div class="navi-left">
    <div class="navi-title on">标签1</div>
    <div class="navi-title">标签2</div>
    <div class="navi-title">标签3</div>
    <div class="navi-title">标签4</div>
  </div>
  <div class="navi-right">
    <div class="navi-right-item" style="display: block;">内容1</div>
    <div class="navi-right-item">内容2</div>
    <div class="navi-right-item">内容3</div>
    <div class="navi-right-item">内容4</div>
  </div>
</div>

JS代码:

// 首页项目tab by Simon
$(document).ready(function(e) {
  $('.navi-left>div').mouseover(function() {
    $(this).addClass('on').siblings('div').removeClass('on');
    $('.navi-right>div:eq(' + $(this).index() + ')').fadeIn(0).siblings().hide()
  })
});

我们先为整个布局画出一个区域.navi-section,然后分为两列:.navi-left.navi-right;左边边为菜单,右边为内容,一一对应。

下面的JS代码监听鼠标行为,当鼠标悬停在.navi-left>div(navi-left内部的div上,及单个菜单区域),将on类添加到该标签上,我们变可以通过给on这个类添加对应的CSS样式;同时我们将其他同级别div(siblings('div'))去除on类,这个动作可以保证所有的菜单中只有一个有on类。

再下面一行JS代码也是同时进行的,当鼠标悬停在.navi-left>div的时候,.navi-right>div:eq表示的是同级别对应的.navi-right中的div(上面有说到一一对应),即菜单1对应内容1,以此类推。此时显示对应的内容,而其他的同级内容全部隐藏。

因为CSS的设计不影响到功能的实现,所以具体的CSS样式表就不贴了,大家可以根据自己的需要来定义,我自己使用了flex布局。

为什么我们不通过显示及隐藏内容栏的方法来对菜单栏进行操作呢?因为如果也按同样的方式设置,那当鼠标移除整个菜单区域的时候就会变回初始状态,而我们希望的是当我们的鼠标移动到某个菜单查看对应内容,当鼠标移走之后该菜单的选中状态以及对应的内容仍然保持显示。那么最好的方法就是给菜单添加一个类,而这个类只有当切换菜单的时候才会转移,而不会消失。

这也是方法一和方法二最主要的区别,因为添加及删除类只有通过JS才可以完成。如果只需要在鼠标悬停在某个菜单上时显示对于内容,移走时什么都不显示,那完全可以通过纯CSS实现。

方法二:纯CSS实现

CSS实现的原理主要是对菜单:hover状态的定义,先放上代码:

HTML代码:

<div class="menu-outer">
  <div class="menu-item">
    <div class="left">菜单1
      <div class="right">内容1</div>
    </div>
  </div>
  <div class="menu-item">
    <div class="left">菜单2
      <div class="right">内容2</div>
    </div>
  </div>
  <div class="menu-item">
    <div class="menu left">菜单3
      <div class="right">内容3</div>
    </div>
  </div>
</div>

JS代码:

.menu-outer{border:1px solid;width:311px;position:relative;}
.left{width:100px;margin:0 10px 0 0;border-bottom:1px solid;border-right:1px solid;padding:5px;background-color:#eee;text-align:center;}
.menu{border-bottom:0;}
.right{display:none;position:absolute;top:9px;left:120px;width:180px;height:78px;padding:10px;}
.left:hover{color:#fff;background-color:#1abc9c;border-color:#000;}
.left:hover .right{display:block;background-color:#1abc9c;}

这边我们来看一下代码,同样的我们先划定一个区域.menu-outer,为了和方法一区分,我这边用了一些不一样的类名。

下面这边和方法一有比较大的区别,在方法一中我们是创建了两个dom(navi-leftnavi-right),然后分别在navi-left中加入菜单,在navi-right中加入内容。但是由于CSS的:hover只对子元素有效,因此我们这边需要像列表一样将所有的菜单做成列表,然后把内容放在对应的菜单内部。

接下来我们需要对leftright的样式做一些定义,比如right的显示方式设置为absolute,这样可以很好的将不显示的内容块隐藏起来,同时就需要对它的位置做一些定义。

下面是这个方法的主要内容,默认隐藏right的内容,否则右侧的内容会被层叠在同一个位置,造成覆盖。当left中的菜单被:hover时,才显示right的内容,由于:hover只对子元素有效,因此只会展现对应菜单的内容。

我在上面的CSS中加了一些多余的样式,是为了大家复制过去的之后有更直观的感受。

演示:

方法三:原生JavaScript实现

部分使用WordPress的同学向我反映方法一种在自己的WordPress中无效。虽然更新了WordPress的jQuery版本后这个菜单切换的功能可以使用,但是主题所使用的页面上的一些js功能还是有冲突失效了,那么我这边就再来问大家介绍一种原生JavaScript实现菜单切换的方法,这种方法不需要加载jQuery,同时也不会和jQuery发送冲突。我们之间来看代码:

HTML代码:

<div class="navi-section">
  <div id="tab-menu" class="navi-left">
    <div class="tab-link active">菜单1</div>
    <div class="tab-link">菜单2</div>
    <div class="tab-link">菜单3</div>
    <div class="tab-link">菜单4</div>
  </div>
  <ul id="tab-content" class="navi-right">
    <li class="tab-panel" style="display:block">
      内容1
    </li>
    <li class="tab-panel" style="display:none">
      内容2
    </li>
    <li class="tab-panel" style="display:none">
      内容3
    </li>
    <li class="tab-panel" style="display:none">
      内容4
    </li>
  </ul>
</div>

JS代码:

function tab(tabMenu,tabLink,tabContent,tabPanel,tabEffect,fn){
 // tabMenu - Tab 导航 ,tabLink 为其中每个点击块
 // tabContent - Tab 内容 ,tabPanel 为其中每个内容块
 // tabEffect 效果,可以自定义切换效果,可以配合animate.css或者其它一些CSS3效果库一起使用
 var tabMenu = document.getElementById(tabMenu);
 var tabContent = document.getElementById(tabContent);
 var tabMenuL = tabMenu.getElementsByTagName(tabLink);
 var tabContentUl = tabContent.getElementsByTagName(tabPanel);
 var tabLen = tabMenuL.length;
 var oldLinkClass = tabMenuL[1].className;
 var oldClass = tabContentUl[0].className;
 for(var i=0;i<tabLen;i++){
 tabMenuL[i].index = i;
 tabMenuL[i].onmouseover = function(){
 for(var i=0;i<tabLen;i++){
 tabContentUl[i].className = oldClass;
 tabContentUl[i].style.display = 'none';
 tabMenuL[i].className = oldLinkClass;
 }
 this.className = oldLinkClass + ' ' + ' active';
 tabContentUl[this.index].style.display = 'block';
 if(fn){fn()}
 if(tabEffect){tabContentUl[this.index].className = oldClass + ' ' + tabEffect;}
 }
 }
}

这种方式的实现原理和方法一相同,相同的部分就不再说了。不过是自己创建了一个tab()函数,而不是通过jQuery的方法,另外我对这个代码进行了修改,使得可以在全局方便的使用tab()函数调用这个功能,只需要在要使用的页面底部加入tab()带上参数的js,如:tab('tab-menu','div','tab-content','li'); 即可使用。

原生JavaScript的方法和方法一在HTML代码中主要的区别是我们需要为左边的菜单列和右边的内容列加入id,这个id需要和调用tab()函数中第1、3个参数一致,另外我加入了和方法一中一致的.navi-left.navi-right类,这样如果你是从方法一改成方法三,可以很好地继承方法一的CSS样式。而左边菜单的菜单项目和右边内容的项目则是对应tab()函数中第2、4个参数;这边注意到左边的子菜单我们定义是div,但是如果左边需要展示的内容层级有多个div就不建议使用div了,也可以和右侧一样换成列表标签li,或者使用a标签,这样可以保证函数找到的是唯一的标签。

好啦,三种方法都为大家介绍完了,自以为还是挺详细的,小白的话也可以完全照着模仿。这三种方法满足的功能基本是一致的,不过每种方法有不同的适用场景,大家建议先了解自己场景的需求到底是什么,再选择适合的方法。当然,怕jQuery兼容性出问题的同学可以看一下方法一的逻辑再使用方法三。如果遇到问题可以自己先排查,还是不行的话可以在本文下面留言。

有BUG或者更好的方法也欢迎告诉我,谢谢!

爱鱼客著作权所有!未经允许不得转载:爱鱼客 » 新手向:三种方法实现页面标签切换展示(JavaScript、CSS、jQuery)

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址