zoukankan      html  css  js  c++  java
  • 简单、通用的JQuery Tab实现

    网页上的空间是寸土寸金,虽然显示器的分辨率越来越大,可是直到今天,网页设计中仍然是以至少1024x768 像素的支持为主,也就是说,每一屏页面只有区区 955x600像素 的安全尺寸可以用而已。于是,为了在有限的空间里容纳更多的内容,滑动门式的标签切换(Tabs)方式越来越受欢迎。通过滑动门技术,可以在同一块页面区域内放置数倍的内容。根据用户的选择来决定显示哪一部分。最近我在实际应用中,逐步完善出一种基于 jQuery,但是比 jQuery UI Tabs 插件更小巧也更通用的简单 Tabs 实现。

    最早的滑动门的技术,一般都是结合 onclick 或者 onmouseover 事件传递一个参数给 JS 函数,根据传递的参数来决定显示哪一个标签。比如:

    function showTabs(n) {
      var tabsNumber = 3;
      for (i = 0; i < tabsNumber; i++) {
          if (i == n) {
              document.getElementById("tabPanel-" + i).style.display = "block";
          } else {
              document.getElementById("tabPanel-" + i).style.display = "none";
          }
      }
    }

    加入有这样的一个函数,就可以在tab的标题按钮中设置 onclick = “showTabs(1)”来设置第二块内容显示,而其它块隐藏。

    这种方式最大的缺点是:

    1. HTML代码和JS代码混合;
    2. 可扩展性差;

    尽管可以通过window.onload绑定事件等方式来是实现JS代码从HTML中分离,也可以把函数改得更复杂以实现通用性。但是总的来说,还是很难做到一处定义到处引用。

    后来随着各种JS类库的出现,更强大的Tabs出现了,最出名的就是jQuery UI中的tabs插件。一旦加载了jQuery框架和jQuery UI插件,那么要在页面中实现Tabs,就变得简单了许多。首先我们的页面中的Tabs代码这样写:

    <div class="tabs">
        <ul>
            <li><a href="#panel-1">标签一</a></li>
            <li><a href="#panel-2">标签二</a></li>
        </ul>
        <div id="panel-1">区域一</div>
        <div id="panel-2">区域二</div>
    </div>

    注意:这里的代码非常干净,不含任何的JS代码或者与文档结构无关的定义。然后,在head区域,或者在页面任何地方增加一段js代码:

    $(function() {
        $(".tabs").tabs();
    });

    就实现了Tabs功能,这行JS代码执行后,上面的HTML代码就会变成:

    <div class="tabs">
        <ul class="ui-tabs-nav" jquery1239647486215="2">
            <li class="ui-tabs-selected"><a href="#panel-1" jquery1239647486215="8">标签一</a></li>
            <li><a href="#panel-2" jquery1239647486215="9">标签二</a></li>
            ></ul>
        <div id="panel-1" class="ui-tabs-panel" jquery1239647486215="4">
            区域一
        </div>
        <div id="panel-2" class="ui-tabs-panel ui-tabs-hide" jquery1239647486215="5">
            区域二
        </div>
    </div>

    结合我们自己编写的css,或者jQuery UI 自带的CSS,就可以实现滑动门效果。并且,由于jQuery的强大,我们可以在页面中放置多组滑动门,然后一次性设定。

    要说明的是,这个地方由于只启用了jQuery UI 中的 Tabs 插件,因此生成的代码还是比较干净的,只增加了 ui-tabs-xxxx 这几个相关的css类。如果你同时包含了jQuery UI的其它插件,那么即使不启用,也会添加一堆的css定义。而且,jQuery UI Tabs 还提供了非常强大的控制功能,你可以动态地添加 tab,可以随意更改激活事件,可以定义切换效果,还可以设置默认激活状态和禁用等。

    但是我在实际应用中遇到了一些问题,除了 jQuery UI 自带的js脚本很大,css不符合实际应用需求外,还有一个最大的问题,你可能已经注意到了,在作为导航的标签定义中,每个标签对应哪一个区域是用链接目标来定义的。比如 <a href="#panel-1">标签一</a>和<div id="panel-1">区域一</div>对应,如果你的标签和区域没有对应起来,绑定tabs()就不起作用了。

    而且,这种方式来带来另一个麻烦,就是当我们需要给标签加上链接的时候,没办法加。即使你将标签的激活事件设置为onmouseover而不是onclick,链接也不能实现,因为链接用于指定目标了。这种需求在我们的实际应用中并不是不存在的。比如: imageimage

    这两个图片中的tabs标签,都要添加到对应的新闻类别或者论坛板块的链接。这时候 jQuery UI的默认绑定就带来了麻烦。

    其实分析一下,我们在实现滑动门的时候,用以下HTML结构就可以满足需要:

    <div class="tabs">
        <ul>
            <li>标签一</li>
            <li>标签二</li>
        </ul>
        <div>区域一</div>
        <div>区域二</div>
    </div>

    借助 jQuery 库,我们可以通过 $(".tabs")找到要实现的标签,然后 .find("li") 来找到要添加事件的元素,绑定事件的时候,我们可以通过该元素在$(".tabs li")集合中的索引值来明确是哪一个标签被激活,然后对应索引值的panel显示。代码类似这样:

    <script type="text/javascript">
        $(function() {
            $(".tabs").find("li").onmouseover(function(e) {
                if (e.target == this) {
                    var tabs = $(this).parent().children("li");
                    var panels = $(this).parent().parent().children("div");
                    var index = $.inArray(this, tabs);
                    if (panels.eq(index)[0]) {
                        tabs.removeClass("ui-tabs-selected")
                            .eq(index).addClass("ui-tabs-selected");
                        panels.addClass("ui-tabs-hide")
                            .eq(index).removeClass("ui-tabs-hide");
                    }
                }
            });
        });
    </script>

    这段代码只使用了两个css类来处理,并且,自动判断tabs和panels的对应状态,假如你有4个tab,但是只有前三个启用了,那么你只需要写三个panel就可以,第四个panel不存在,则第四个tab自动不生效。

    在实际使用中,会遇到一个问题,一般我们会给tab中的文字加链接,那么当鼠标滑过这个tab的时候,如果指到了文字,那么激发事件的对象有可能是a元素而不是li元素,则事件就不能正确激发。所以我们改进代码如下:

    <script type="text/javascript">
        $(function() {
            $(".ui-tabs-nav > li > a")onmouseover(function(e) {
                if (e.target == this) {
                    var tabs = $(this).parent().parent().children("li");
                    var panels = $(this).parent().parent().parent().children(".ui-tabs-panel");
                    var index = $.inArray(this, tabs);
                    if (panels.eq(index)[0]) {
                        tabs.removeClass("ui-tabs-selected")
                            .eq(index).addClass("ui-tabs-selected");
                        panels.addClass("ui-tabs-hide")
                            .eq(index).removeClass("ui-tabs-hide");
                    }
                }
            });
        });
    </script>

    与此对应的HTML结构是:

    <div>
        <ul class="ui-tabs-nav">
            <li class="ui-tabs-selected"><a href="/bbs">论坛新帖</a></li>
            <li><a href="/blog">最新博文</a></li>
        </ul>
        <div class="ui-tabs-panel">
          <!--这里调用最新论坛文章-->
        </div>
        <div class="ui-tabs-panel ui-tabs-hide">
          <!--这里调用最新博客文章-->
        </div>
    </div>

    同时,我们有以下的css类定义:

    .ui-tabs-nav
    {
        /*导航容器定义*/
    }
    .ui-tabs-nav li
    {
        /*默认标签样式*/
    }
    .ui-tabs-nav li.ui-tabs-selected
    {
        /*激活的标签样式*/
    }
    .ui-tabs-panel
    {
        /*默认的显示区域样式*/
    }
    .ui-tabs-hide
    {
        display: none;
    }

    这样,就可以根据你的需要,结合自己的css,定制不同样式的滑动门了。把相应的js代码放到页面中,那么在页面里任何地方只要你按照HTML结构编写了一段html,这段html就会自动变成滑动门。而不用在每个页面里单独指定特定的selector来应用滑动门的tabs()方法。并且,根据需要给你的滑动门标签添加需要的链接,或者不要链接(href="#" 或者 href="javascript:void(0)")。

    这段滑动门代码只要具有jQuery core 就可以正常运行,不需要加载jQuery UI。非常简单,而且很通用,样式上喜欢怎么扩展都可以。

    具体效果可以参见 http:/www.taihainet.com , 在 台海网 首页中,我一共应用了四个样式共九组滑动门,代码就只是上面给出的那一段。四个样式列举如下:

    image  滑动门一:多个搜索表单,暂时只实现两个,后面三个由于没有对应的ui-tabs-panel,自动禁用,但是链接可以点击。

    image  滑动门二:多块商务信息区域,其中第三个由于没有对应的ui-tabs-panel,自动禁用。

    image 滑动门三:新闻栏目切换,标签中的文字链接到对应的新闻栏目。

    image 滑动门四:论坛分板块帖子调用。标签中的文字链接到对应的论坛板块。

    本文首发自 刀刀博客,博客园同步更新。如需转载,请注明作者及出处。
  • 相关阅读:
    VisualSVN-Server windows 版安装时报错 "Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details."
    Pytest 单元测试框架之初始化和清除环境
    Pytest 单元测试框架入门
    Python(email 邮件收发)
    Python(minidom 模块)
    Python(csv 模块)
    禅道简介
    2020年最好的WooCommerce主题
    Shopify网上开店教程(2020版)
    WooCommerce VS Magento 2020:哪个跨境电商自建站软件更好?
  • 原文地址:https://www.cnblogs.com/zhangchuan/p/3018682.html
Copyright © 2011-2022 走看看