Amaze UI

Tabs


选项卡插件,基于 CSS3 transition 实现水平平滑滚动;CSS3 动画实现回弹效果(触控操作时)。

基础用法

大江东去,浪淘尽,千古风流人物。 故垒西边,人道是,三国周郎赤壁。 乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。 遥想公瑾当年,小乔初嫁了,雄姿英发。 羽扇纶巾,谈笑间,樯橹灰飞烟灭。 故国神游,多情应笑我,早生华发。 人生如梦,一尊还酹江月。A
大江东去,浪淘尽,千古风流人物。 故垒西边,人道是,三国周郎赤壁。 乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。 遥想公瑾当年,小乔初嫁了,雄姿英发。 羽扇纶巾,谈笑间,樯橹灰飞烟灭。 故国神游,多情应笑我,早生华发。 人生如梦,一尊还酹江月。B
大江东去,浪淘尽,千古风流人物。 故垒西边,人道是,三国周郎赤壁。 乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。 遥想公瑾当年,小乔初嫁了,雄姿英发。 羽扇纶巾,谈笑间,樯橹灰飞烟灭。 故国神游,多情应笑我,早生华发。 人生如梦,一尊还酹江月。 C
Copy
<style>
  .am-tabs-nav li {
    position: relative;
    z-index: 1;
  }

  .am-tabs-nav .am-icon-close {
    position: absolute;
    top: 0;
    right: 10px;
    color: #888;
    cursor: pointer;
    z-index: 100;
  }

  .am-tabs-nav .am-icon-close:hover {
    color: #333;
  }

  .am-tabs-nav .am-icon-close ~ a {
    padding-right: 25px!important;
  }
</style>

<div class="am-tabs" data-am-tabs>
  <ul class="am-tabs-nav am-nav am-nav-tabs">
    <li class="am-active"><a href="javascript: void(0)">选项A</a></li>
    <li><a href="javascript: void(0)">选项B</a></li>
    <li><a href="javascript: void(0)">选项C</a></li>
  </ul>

  <div class="am-tabs-bd">
    <div class="am-tab-panel am-active">
      大江东去,浪淘尽,千古风流人物。
      故垒西边,人道是,三国周郎赤壁。
      乱石穿空,惊涛拍岸,卷起千堆雪。
      江山如画,一时多少豪杰。
      遥想公瑾当年,小乔初嫁了,雄姿英发。
      羽扇纶巾,谈笑间,樯橹灰飞烟灭。
      故国神游,多情应笑我,早生华发。
      人生如梦,一尊还酹江月。A
    </div>
    <div class="am-tab-panel">
      大江东去,浪淘尽,千古风流人物。
      故垒西边,人道是,三国周郎赤壁。
      乱石穿空,惊涛拍岸,卷起千堆雪。
      江山如画,一时多少豪杰。
      遥想公瑾当年,小乔初嫁了,雄姿英发。
      羽扇纶巾,谈笑间,樯橹灰飞烟灭。
      故国神游,多情应笑我,早生华发。
      人生如梦,一尊还酹江月。B
    </div>
    <div class="am-tab-panel">
      大江东去,浪淘尽,千古风流人物。
      故垒西边,人道是,三国周郎赤壁。
      乱石穿空,惊涛拍岸,卷起千堆雪。
      江山如画,一时多少豪杰。
      遥想公瑾当年,小乔初嫁了,雄姿英发。
      羽扇纶巾,谈笑间,樯橹灰飞烟灭。
      故国神游,多情应笑我,早生华发。
      人生如梦,一尊还酹江月。 C
    </div>
  </div>
</div>

内容高度一致

在容器上添加.am-tabs.am-tabs-nav放置标题,.am-tabs-bd放置内容。

在线运行

动态插入、删除选项卡

大江东去,浪淘尽,千古风流人物。 故垒西边,人道是,三国周郎赤壁。 乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。 遥想公瑾当年,小乔初嫁了,雄姿英发。 羽扇纶巾,谈笑间,樯橹灰飞烟灭。 故国神游,多情应笑我,早生华发。 人生如梦,一尊还酹江月。A
大江东去,浪淘尽,千古风流人物。 故垒西边,人道是,三国周郎赤壁。 乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。 遥想公瑾当年,小乔初嫁了,雄姿英发。 羽扇纶巾,谈笑间,樯橹灰飞烟灭。 故国神游,多情应笑我,早生华发。 人生如梦,一尊还酹江月。B
大江东去,浪淘尽,千古风流人物。 故垒西边,人道是,三国周郎赤壁。 乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。 遥想公瑾当年,小乔初嫁了,雄姿英发。 羽扇纶巾,谈笑间,樯橹灰飞烟灭。 故国神游,多情应笑我,早生华发。 人生如梦,一尊还酹江月。 C

Copy
<style>
  .am-tabs-nav li {
    position: relative;
    z-index: 1;
  }

  .am-tabs-nav .am-icon-close {
    position: absolute;
    top: 0;
    right: 10px;
    color: #888;
    cursor: pointer;
    z-index: 100;
  }

  .am-tabs-nav .am-icon-close:hover {
    color: #333;
  }

  .am-tabs-nav .am-icon-close ~ a {
    padding-right: 25px!important;
  }
</style>
<div class="am-tabs" data-am-tabs="{noSwipe: 1}" id="doc-tab-demo-1">
  <ul class="am-tabs-nav am-nav am-nav-tabs">
    <li class="am-active"><a href="javascript: void(0)">选项A</a></li>
    <li><a href="javascript: void(0)">选项B</a></li>
    <li><a href="javascript: void(0)">选项C</a></li>
  </ul>

  <div class="am-tabs-bd">
    <div class="am-tab-panel am-active">
      大江东去,浪淘尽,千古风流人物。
      故垒西边,人道是,三国周郎赤壁。
      乱石穿空,惊涛拍岸,卷起千堆雪。
      江山如画,一时多少豪杰。
      遥想公瑾当年,小乔初嫁了,雄姿英发。
      羽扇纶巾,谈笑间,樯橹灰飞烟灭。
      故国神游,多情应笑我,早生华发。
      人生如梦,一尊还酹江月。A
    </div>
    <div class="am-tab-panel">
      大江东去,浪淘尽,千古风流人物。
      故垒西边,人道是,三国周郎赤壁。
      乱石穿空,惊涛拍岸,卷起千堆雪。
      江山如画,一时多少豪杰。
      遥想公瑾当年,小乔初嫁了,雄姿英发。
      羽扇纶巾,谈笑间,樯橹灰飞烟灭。
      故国神游,多情应笑我,早生华发。
      人生如梦,一尊还酹江月。B
    </div>
    <div class="am-tab-panel">
      大江东去,浪淘尽,千古风流人物。
      故垒西边,人道是,三国周郎赤壁。
      乱石穿空,惊涛拍岸,卷起千堆雪。
      江山如画,一时多少豪杰。
      遥想公瑾当年,小乔初嫁了,雄姿英发。
      羽扇纶巾,谈笑间,樯橹灰飞烟灭。
      故国神游,多情应笑我,早生华发。
      人生如梦,一尊还酹江月。 C
    </div>
  </div>
</div>
<br />
<button type="button" class="am-btn am-btn-primary js-append-tab">插入 Tab</button>
<script>
  $(function() {
    var tabCounter = 0;
    var $tab = $('#doc-tab-demo-1');
    var $nav = $tab.find('.am-tabs-nav');
    var $bd = $tab.find('.am-tabs-bd');

    function addTab() {
      var nav = '<li><span class="am-icon-close"></span>' +
        '<a href="javascript: void(0)">标签 ' + tabCounter + '</a></li>';
      var content = '<div class="am-tab-panel">动态插入的标签内容' + tabCounter + '</div>';

      $nav.append(nav);
      $bd.append(content);
      tabCounter++;
      $tab.tabs('refresh');
    }

    // 动态添加标签页
    $('.js-append-tab').on('click', function() {
      addTab();
    });

    // 移除标签页
    $nav.on('click', '.am-icon-close', function() {
      var $item = $(this).closest('li');
      var index = $nav.children('li').index($item);

      $item.remove();
      $bd.find('.am-tab-panel').eq(index).remove();

      $tab.tabs('open', index > 0 ? index - 1 : index + 1);
      $tab.tabs('refresh');
    });
  });
</script>

自适应内容高度

大江东去,浪淘尽,千古风流人物。
故垒西边,人道是,三国周郎赤壁。
乱石穿空,惊涛拍岸,卷起千堆雪。
江山如画,一时多少豪杰。
大江东去
浪淘尽
千古风流人物
故垒西边
人道是
三国周郎赤壁
恨乱石穿空
惊涛拍岸
卷起千堆雪
江山如画
一时多少豪杰
大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。
Copy
<div class="am-tabs" data-am-tabs>
  <ul class="am-tabs-nav am-nav am-nav-tabs">
    <li class="am-active"><a href="#tab1">选项A</a></li>
    <li><a href="#tab2">选项B</a></li>
    <li><a href="#tab3">选项C</a></li>
  </ul>

  <div class="am-tabs-bd">
    <div class="am-tab-panel am-fade am-in am-active" id="tab1">
      大江东去,浪淘尽,千古风流人物。<br>故垒西边,人道是,三国周郎赤壁。<br>乱石穿空,惊涛拍岸,卷起千堆雪。<br>江山如画,一时多少豪杰。
    </div>
    <div class="am-tab-panel am-fade" id="tab2">
      大江东去<br>浪淘尽<br>千古风流人物<br>故垒西边<br>人道是<br>三国周郎赤壁<br>恨乱石穿空<br>惊涛拍岸<br>卷起千堆雪<br>江山如画<br>一时多少豪杰
    </div>
    <div class="am-tab-panel am-fade" id="tab3">
      大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。
    </div>
  </div>
</div>

禁用触控操作

大江东去,浪淘尽,千古风流人物。
故垒西边,人道是,三国周郎赤壁。
乱石穿空,惊涛拍岸,卷起千堆雪。
江山如画,一时多少豪杰。
大江东去
浪淘尽
千古风流人物
故垒西边
人道是
三国周郎赤壁
恨乱石穿空
惊涛拍岸
卷起千堆雪
江山如画
一时多少豪杰
大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。
Copy
<div class="am-tabs" data-am-tabs="{noSwipe: 1}">
  <ul class="am-tabs-nav am-nav am-nav-tabs">
    <li class="am-active"><a href="#tab2-1">选项A</a></li>
    <li><a href="#tab2-2">选项B</a></li>
    <li><a href="#tab2-3">选项C</a></li>
  </ul>

  <div class="am-tabs-bd">
    <div class="am-tab-panel am-fade am-in am-active" id="tab2-1">
      大江东去,浪淘尽,千古风流人物。<br>故垒西边,人道是,三国周郎赤壁。<br>乱石穿空,惊涛拍岸,卷起千堆雪。<br>江山如画,一时多少豪杰。
    </div>
    <div class="am-tab-panel am-fade" id="tab2-2">
      大江东去<br>浪淘尽<br>千古风流人物<br>故垒西边<br>人道是<br>三国周郎赤壁<br>恨乱石穿空<br>惊涛拍岸<br>卷起千堆雪<br>江山如画<br>一时多少豪杰
    </div>
    <div class="am-tab-panel am-fade" id="tab2-3">
      大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。
    </div>
  </div>
</div>

部分用户反应在过长的 Tabs 中滚动页面时会意外触发 Tab 切换事件,用户可以选择禁用触控操作。

在线运行

Tab 内容溢出容器问题

大江东去,浪淘尽,千古风流人物。
故垒西边,人道是,三国周郎赤壁。
乱石穿空,惊涛拍岸,卷起千堆雪。
江山如画,一时多少豪杰。
大江东去
浪淘尽
千古风流人物
故垒西边
人道是
三国周郎赤壁
恨乱石穿空
惊涛拍岸
卷起千堆雪
江山如画
一时多少豪杰
大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。
Copy
<div class="am-tabs" data-am-tabs>
  <ul class="am-tabs-nav am-nav am-nav-tabs">
    <li class="am-active"><a href="#tab-4-1">选项A</a></li>
    <li><a href="#tab-4-2">选项B</a></li>
    <li><a href="#tab-4-3">选项C</a></li>
  </ul>
  <div class="am-tabs-bd am-tabs-bd-ofv">
    <div class="am-tab-panel am-active" id="tab-4-1">
       大江东去,浪淘尽,千古风流人物。<br>故垒西边,人道是,三国周郎赤壁。<br>乱石穿空,惊涛拍岸,卷起千堆雪。<br>江山如画,一时多少豪杰。
       <br />
        <div class="am-dropdown" data-am-dropdown>
          <button class="am-btn am-btn-primary am-dropdown-toggle" data-am-dropdown-toggle>下拉列表 <span class="am-icon-caret-down"></span></button>
          <ul class="am-dropdown-content">
            <li class="am-dropdown-header">标题</li>
            <li><a href="#">大江东去</a></li>
            <li class="am-active"><a href="#">浪淘尽</a></li>
            <li><a href="#">千古风流人物</a></li>
            <li class="am-disabled"><a href="#">故垒西边</a></li>
            <li class="am-divider"></li>
            <li><a href="#">人道是 三国周郎赤壁</a></li>
          </ul>
        </div>
    </div>
    <div class="am-tab-panel" id="tab-4-2">
      大江东去<br>浪淘尽<br>千古风流人物<br>故垒西边<br>人道是<br>三国周郎赤壁<br>恨乱石穿空<br>惊涛拍岸<br>卷起千堆雪<br>江山如画<br>一时多少豪杰
    </div>
    <div class="am-tab-panel" id="tab-4-3">
      大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。
    </div>
  </div>
</div>

为了实现动画效果,标签内容容器 .am-tabs-bd 上添加了 overflow: hidden,在某些场景会有一些问题(#833#901),目前的处理方式是在 .am-tabs-bd 上添加 .am-tabs-bd-ofv(动画效果会被取消)。

在线运行

调用方式

通过 Data API

在选项卡容器 .am-tabs 上添加 data-am-tabs 属性。上面的演示即通过此种方式调用。

<div class="am-tabs" data-am-tabs>
  <ul class="am-tabs-nav am-nav am-nav-tabs">
    <li class="am-active"><a href="#tab1">恣意</a></li>
    <li><a href="#tab2">等候</a></li>
    <li><a href="#tab3">流浪</a></li>
  </ul>

  <div class="am-tabs-bd">
    <div class="am-tab-panel am-active" id="tab1">...</div>
    <div class="am-tab-panel" id="tab2">...</div>
    <div class="am-tab-panel" id="tab3">...</div>
  </div>
</div>

通过 JS

选项

  • options.noSwipe 是否禁用触控事件。
$('#someTabs').tabs({noSwipe: 1});

方法

大江东去,浪淘尽,千古风流人物。
故垒西边,人道是,三国周郎赤壁。
乱石穿空,惊涛拍岸,卷起千堆雪。
Copy
<div class="am-tabs" id="doc-my-tabs">
  <ul class="am-tabs-nav am-nav am-nav-tabs am-nav-justify">
    <li class="am-active"><a href="">第一句</a></li>
    <li><a href="">第二句</a></li>
    <li><a href="">第三句</a></li>
  </ul>
  <div class="am-tabs-bd">
    <div class="am-tab-panel am-active">大江东去,浪淘尽,千古风流人物。</div>
    <div class="am-tab-panel">故垒西边,人道是,三国周郎赤壁。</div>
    <div class="am-tab-panel">乱石穿空,惊涛拍岸,卷起千堆雪。</div>
  </div>
</div>
<script>
  $(function() {
    var $myTabs = $('#doc-my-tabs');

    $myTabs.tabs();

    $myTabs.find('a').on('opened.tabs.amui', function(e) {
      console.log('[%s] 选项卡打开了', $(this).text());
    })
  })
</script>
  • $().tabs(options) - 初始化选项卡;
  • $().tabs('open', index) - 切换到指定的标签页,index 可以是数值或 jQuery 对象(选择符),如 $('.am-tabs-nav a').eq(2)
  • $().tabs('refresh') - 刷新选项卡,动态添加、移除标签页后需手动刷新;
  • $().tabs('destroy') - 销毁选项卡。

在线运行

自定义事件

自定义事件触发在标签上。

事件名称描述
open.tabs.amui打开一个选项卡时立即触发
opened.tabs.amui选项卡打开完成时触发(CSS 动画执行完成)
$('#doc-my-tabs').find('a').on('opened.tabs.amui', function(e) {
  console.log('[%s] 选项卡打开了', $(this).text());
})

打开控制台操作上面的选项卡查看事件监听输出的文字。

FAQ

Tab 内容不能选择,如何处理?

这个问题由 Hammer.js 引起。

Hammer is setting a property to improve the UX of the panning on desktop.

可以使用下面的样式覆盖掉 Hammer.js 的样式:

.am-tabs-bd {
  -moz-user-select: text !important;
  -webkit-user-select: text !important;
  -ms-user-select: text !important;
  user-select: text !important;
}

也可以选择禁用触控事件。