标签页插件可与 导航组件(例如 .nav-tabs 和 .nav-pills)以及 列表组 一起使用。
导航标签
添加所需的数据属性并 id 将其添加到你的导航以使其可通过标签键访问。然后,添加 tab-content 带匹配的容器 id到每个标签页面板。
这是一些占位内容 首页标签页的 相关内容。
这是一些占位内容 个人资料标签的 相关内容。
这是一些占位内容 联系人标签的 相关内容。
这是一些占位内容 已禁用标签的 相关内容。
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home-tab-pane" type="button" role="tab" aria-controls="home-tab-pane" aria-selected="true">Home</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile-tab-pane" type="button" role="tab" aria-controls="profile-tab-pane" aria-selected="false">Profile</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact-tab-pane" type="button" role="tab" aria-controls="contact-tab-pane" aria-selected="false">Contact</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="disabled-tab" data-bs-toggle="tab" data-bs-target="#disabled-tab-pane" type="button" role="tab" aria-controls="disabled-tab-pane" aria-selected="false" disabled>Disabled</button>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane show active" id="home-tab-pane" role="tabpanel" aria-labelledby="home-tab" tabindex="0">
<p>This is some placeholder content the <strong>Home tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="profile-tab-pane" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">
<p>This is some placeholder content the <strong>Profile tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="contact-tab-pane" role="tabpanel" aria-labelledby="contact-tab" tabindex="0">
<p>This is some placeholder content the <strong>Contact tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="disabled-tab-pane" role="tabpanel" aria-labelledby="disabled-tab" tabindex="0">
<p>This is some placeholder content the <strong>Disabled tab’s</strong> associated content.</p>
</div>
</div>带按钮
为了更好地满足你的需求,这可以与如上所示的<ul>基础标记一起使用,或与任何任意的“自定义”标记一起使用。请注意,如果你正在使用<nav>,则不应直接向其添加role="tablist",因为这会覆盖该元素作为导航标记的原生角色。相反,应切换到其他元素(在下面的示例中,一个简单的<div>)并将<nav>包裹在其周围。
<nav>
<div class="nav nav-tabs" id="nav-tab2" role="tablist">
<button class="nav-link active" id="nav-home-tab2" data-bs-toggle="tab" data-bs-target="#nav-home2" type="button" role="tab" aria-controls="nav-home2" aria-selected="true">Home</button>
<button class="nav-link" id="nav-profile-tab2" data-bs-toggle="tab" data-bs-target="#nav-profile2" type="button" role="tab" aria-controls="nav-profile2" aria-selected="false">Profile</button>
<button class="nav-link" id="nav-contact-tab2" data-bs-toggle="tab" data-bs-target="#nav-contact2" type="button" role="tab" aria-controls="nav-contact2" aria-selected="false">Contact</button>
<button class="nav-link" id="nav-disabled-tab2" data-bs-toggle="tab" data-bs-target="#nav-disabled2" type="button" role="tab" aria-controls="nav-disabled2" aria-selected="false" disabled>Disabled</button>
</div>
</nav>
<div class="tab-content" id="nav-tabContent2">
<div class="tab-pane show active" id="nav-home2" role="tabpanel" aria-labelledby="nav-home-tab2" tabindex="0">
<p>This is some placeholder content the <strong>Home tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="nav-profile2" role="tabpanel" aria-labelledby="nav-profile-tab2" tabindex="0">
<p>This is some placeholder content the <strong>Profile tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="nav-contact2" role="tabpanel" aria-labelledby="nav-contact-tab2" tabindex="0">
<p>This is some placeholder content the <strong>Contact tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="nav-disabled2" role="tabpanel" aria-labelledby="nav-disabled-tab2" tabindex="0">
<p>This is some placeholder content the <strong>Disabled tab’s</strong> associated content.</p>
</div>
</div>药丸
标签插件也适用于药丸式标签页。
这是一些占位内容 首页标签页的 相关内容。
这是一些占位内容 个人资料标签的 相关内容。
这是一些占位内容 联系人标签的 相关内容。
这是一些占位内容 已禁用标签的 相关内容。
<ul class="nav nav-pills" id="pills-tab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="pills-home-tab" data-bs-toggle="tab" data-bs-target="#pills-home" type="button" role="tab" aria-controls="pills-home" aria-selected="true">Home</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="pills-profile-tab" data-bs-toggle="tab" data-bs-target="#pills-profile" type="button" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="pills-contact-tab" data-bs-toggle="tab" data-bs-target="#pills-contact" type="button" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="pills-disabled-tab" data-bs-toggle="tab" data-bs-target="#pills-disabled" type="button" role="tab" aria-controls="pills-disabled" aria-selected="false" disabled>Disabled</button>
</li>
</ul>
<div class="tab-content" id="pills-tabContent">
<div class="tab-pane show active" id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab" tabindex="0">
<p>This is some placeholder content the <strong>Home tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab" tabindex="0">
<p>This is some placeholder content the <strong>Profile tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="pills-contact" role="tabpanel" aria-labelledby="pills-contact-tab" tabindex="0">
<p>This is some placeholder content the <strong>Contact tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="pills-disabled" role="tabpanel" aria-labelledby="pills-disabled-tab" tabindex="0">
<p>This is some placeholder content the <strong>Disabled tab’s</strong> associated content.</p>
</div>
</div>以及垂直药丸。理想情况下,对于垂直标签页,你还应该在标签页列表容器中添加 aria-orientation="vertical"。
这是一些占位内容 首页标签页的 相关内容。
这是一些占位内容 个人资料标签的 相关内容。
这是一些占位内容 已禁用标签的 相关内容。
这是一些占位内容 消息标签的 相关内容。
这是一些占位内容 设置标签的 相关内容。
<div class="d-flex align-items-start">
<div class="nav nav-pills nav-pills-vertical me-4" id="v-pills-tab" role="tablist" aria-orientation="vertical">
<button class="nav-link active" id="v-pills-home-tab" data-bs-toggle="tab" data-bs-target="#v-pills-home" type="button" role="tab" aria-controls="v-pills-home" aria-selected="true">Home</button>
<button class="nav-link" id="v-pills-profile-tab" data-bs-toggle="tab" data-bs-target="#v-pills-profile" type="button" role="tab" aria-controls="v-pills-profile" aria-selected="false">Profile</button>
<button class="nav-link" id="v-pills-disabled-tab" data-bs-toggle="tab" data-bs-target="#v-pills-disabled" type="button" role="tab" aria-controls="v-pills-disabled" aria-selected="false" disabled>Disabled</button>
<button class="nav-link" id="v-pills-messages-tab" data-bs-toggle="tab" data-bs-target="#v-pills-messages" type="button" role="tab" aria-controls="v-pills-messages" aria-selected="false">Messages</button>
<button class="nav-link" id="v-pills-settings-tab" data-bs-toggle="tab" data-bs-target="#v-pills-settings" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false">Settings</button>
</div>
<div class="tab-content" id="v-pills-tabContent">
<div class="tab-pane show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab" tabindex="0">
<p>This is some placeholder content the <strong>Home tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab" tabindex="0">
<p>This is some placeholder content the <strong>Profile tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="v-pills-disabled" role="tabpanel" aria-labelledby="v-pills-disabled-tab" tabindex="0">
<p>This is some placeholder content the <strong>Disabled tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="v-pills-messages" role="tabpanel" aria-labelledby="v-pills-messages-tab" tabindex="0">
<p>This is some placeholder content the <strong>Messages tab’s</strong> associated content.</p>
</div>
<div class="tab-pane" id="v-pills-settings" role="tabpanel" aria-labelledby="v-pills-settings-tab" tabindex="0">
<p>This is some placeholder content the <strong>Settings tab’s</strong> associated content.</p>
</div>
</div>
</div>列表组
该标签插件也适用于 列出群组. 添加 data-bs-toggle="tab" 给每个人 .list-group-item 并将它们搭配 .tab-pane 元素。
<div class="row">
<div class="col-4">
<div class="list-group" id="list-tab" role="tablist">
<a class="list-group-item list-group-item-action active" id="list-home-list" data-bs-toggle="tab" href="#list-home" role="tab" aria-controls="list-home">Home</a>
<a class="list-group-item list-group-item-action" id="list-profile-list" data-bs-toggle="tab" href="#list-profile" role="tab" aria-controls="list-profile">Profile</a>
<a class="list-group-item list-group-item-action" id="list-messages-list" data-bs-toggle="tab" href="#list-messages" role="tab" aria-controls="list-messages">Messages</a>
<a class="list-group-item list-group-item-action" id="list-settings-list" data-bs-toggle="tab" href="#list-settings" role="tab" aria-controls="list-settings">Settings</a>
</div>
</div>
<div class="col-8">
<div class="tab-content" id="list-tabContent">
<div class="tab-pane show active" id="list-home" role="tabpanel" aria-labelledby="list-home-list">
<p>Some placeholder content in a paragraph relating to "Home".</p>
</div>
<div class="tab-pane" id="list-profile" role="tabpanel" aria-labelledby="list-profile-list">
<p>Some placeholder content in a paragraph relating to "Profile".</p>
</div>
<div class="tab-pane" id="list-messages" role="tabpanel" aria-labelledby="list-messages-list">
<p>Some placeholder content in a paragraph relating to "Messages".</p>
</div>
<div class="tab-pane" id="list-settings" role="tabpanel" aria-labelledby="list-settings-list">
<p>Some placeholder content in a paragraph relating to "Settings".</p>
</div>
</div>
</div>
</div>无障碍访问
如 ARIA 作者实践指南 标签页模式 所述,动态标签页界面需要 role="tablist"、role="tab"、role="tabpanel" 以及额外的 aria- 属性,以向辅助技术用户(例如屏幕阅读器)传达其结构、功能和当前状态。作为最佳实践,我们建议为标签页使用 <button> 元素,因为这些是触发动态变化的控件,而不是导航到新页面或位置的链接。
根据 ARIA 编写实践模式,只有当前活动的标签页会接收键盘焦点。当 JavaScript 插件初始化时,它将设置 tabindex="-1" 在所有非活动的标签页控件上。一旦当前活动的标签页获得焦点,光标键就会激活前一个/下一个标签页。 Home 和 End 键分别激活第一个和最后一个标签页。该插件将更改 巡游的 tabindex 因此。然而,请注意,JavaScript 插件在处理光标键交互时不会区分水平和垂直的标签页列表:无论标签页列表的方向如何,向上 和 左光标移到上一个标签页,然后向下 和 右箭头光标移到下一个标签页。
通常,为了便于键盘导航,建议也使标签页面板本身可以获得焦点,除非标签页面板内包含有意义内容的第一个元素已经可以获得焦点。JavaScript 插件不会尝试处理此方面——在适当的情况下,你需要通过在标记中添加 tabindex="0" 明确使你的标签页面板可聚焦。
JavaScript 标签插件不支持包含菜单的标签界面,因为这会导致可用性和可访问性问题。从可用性角度来看,当前显示的标签的触发元素不立即可见(因为它在关闭的菜单中)可能会引起混淆。从可访问性角度来看,目前没有合理的方法将这种结构映射到标准 WAI ARIA 模式,这意味着它无法轻松地让辅助技术用户理解。
用法
通过数据属性
你可以通过简单地在元素上指定data-bs-toggle="tab"来激活标签页导航,而无需编写任何 JavaScript。
| 属性 | 描述 |
|---|---|
data-bs-toggle="tab" | 在触发器上激活标签导航。 |
data-bs-target | 要显示的标签面板的 CSS 选择器(必须与相应的 .tab-pane 配对)。 |
<!-- Nav tabs -->
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home" type="button" role="tab" aria-controls="home" aria-selected="true">Home</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile" type="button" role="tab" aria-controls="profile" aria-selected="false">Profile</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="messages-tab" data-bs-toggle="tab" data-bs-target="#messages" type="button" role="tab" aria-controls="messages" aria-selected="false">Messages</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="settings-tab" data-bs-toggle="tab" data-bs-target="#settings" type="button" role="tab" aria-controls="settings" aria-selected="false">Settings</button>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="home" role="tabpanel" aria-labelledby="home-tab" tabindex="0">...</div>
<div class="tab-pane" id="profile" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">...</div>
<div class="tab-pane" id="messages" role="tabpanel" aria-labelledby="messages-tab" tabindex="0">...</div>
<div class="tab-pane" id="settings" role="tabpanel" aria-labelledby="settings-tab" tabindex="0">...</div>
</div>
通过 JavaScript
通过 JavaScript 启用可切换的标签页(每个标签页需要单独激活):
const triggerTabList = document.querySelectorAll('#myTab button')
triggerTabList.forEach(triggerEl => {
const tabTrigger = new bootstrap.Tab(triggerEl)
triggerEl.addEventListener('click', event => {
event.preventDefault()
tabTrigger.show()
})
})
你可以通过几种方式激活各个标签页:
const triggerEl = document.querySelector('#myTab button[data-bs-target="#profile"]')
bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name
const triggerFirstTabEl = document.querySelector('#myTab li:first-child button')
bootstrap.Tab.getInstance(triggerFirstTabEl).show() // Select first tab
渐隐效果
每个.tab-pane在变为活动状态时都会淡入。你选择的窗格会立即离开,因为两个在流中的窗格无法交叉淡入,除非其中一个叠放在另一个下方。
将 .tab-pane-instant 添加到窗格以切换其淡出,或使用 --bs-tab-pane-transition-* 代币重新调谐它。请参阅 过渡。
<div class="tab-content">
<div class="tab-pane tab-pane-instant show active" id="home" role="tabpanel" aria-labelledby="home-tab" tabindex="0">...</div>
<div class="tab-pane tab-pane-instant" id="profile" role="tabpanel" aria-labelledby="profile-tab" tabindex="0">...</div>
</div>
依赖项
如果你从源代码构建 Bootstrap 的 JS,标签插件需要以下 JavaScript 文件:
| 文件 | 描述 |
|---|---|
js/src/tab.ts | 主标签组件 |
js/src/base-component.ts | 基础组件类 |
js/src/dom/data.ts | 元素数据存储 |
js/src/dom/event-handler.ts | 事件处理工具 |
js/src/dom/manipulator.ts | 数据属性操作 |
js/src/dom/selector-engine.ts | DOM选择器工具 |
js/src/util/config.ts | 配置基础类 |
js/src/util/index.ts | 核心工具函数 |
方法
显示或隐藏组件的方法会返回一个 Promise。 当过渡结束时,该 Promise 会被解析,所以 await 会在 shown.bs.* 或 hidden.bs.* 监听器运行的同一时刻继续。方法仍会立即返回,并且永远不会阻塞调用者。对已在过渡中的组件进行调用不会有任何效果,并会立即解析。在我们的 JavaScript 文档中了解更多。
将你的内容激活为标签页元素。
你可以使用构造函数创建一个标签实例,例如:
const bsTab = new bootstrap.Tab('#myTab')
| 方法 | 描述 |
|---|---|
dispose | 销毁元素的标签。 |
getInstance | 静态方法,允许你获取与 DOM 元素关联的标签实例,你可以这样使用它: bootstrap.Tab.getInstance(element). |
getOrCreateInstance | 静态方法,返回与 DOM 元素关联的标签页实例,如果未初始化则创建一个新的实例。你可以这样使用它: bootstrap.Tab.getOrCreateInstance(element). |
show | 选择给定的标签页并显示其关联的窗格。任何之前被选中的其他标签页将被取消选中,其关联的窗格将被隐藏。 返回一个在标签页面板显示后解析的 Promise (即在……之后 shown.bs.tab 事件触发)。 |
事件
显示新标签页时,事件按以下顺序触发:
hide.bs.tab(在当前活动标签页上)show.bs.tab(在将显示的标签页上)hidden.bs.tab(在之前的活动标签页上,与hide.bs.tab事件相同)shown.bs.tab(在新激活的刚显示的标签页上,与show.bs.tab事件相同)
如果没有标签页已处于活动状态,那么hide.bs.tab和hidden.bs.tab事件将不会被触发。
| 事件类型 | 描述 |
|---|---|
hide.bs.tab | 当要显示新标签页(因此之前的活动标签页将被隐藏)时,会触发此事件。使用 event.target 和 event.relatedTarget 分别定位当前活动标签页和即将成为活动标签页的新标签页。 |
hidden.bs.tab | 此事件在新标签页显示后触发(因此之前的活动标签页被隐藏)。使用 event.target 和 event.relatedTarget 分别针对之前的活动标签页和新的活动标签页。 |
show.bs.tab | 此事件在标签显示时触发,但在新标签显示之前使用 event.target 和 event.relatedTarget 分别针对当前活动标签页和之前的活动标签页(如果有的话)。 |
shown.bs.tab | 此事件在标签页显示后触发,使用时在标签页已显示之后。 event.target 和 event.relatedTarget 分别针对当前活动标签页和之前的活动标签页(如果有的话)。 |
const tabEl = document.querySelector('button[data-bs-toggle="tab"]')
tabEl.addEventListener('shown.bs.tab', event => {
event.target // newly activated tab
event.relatedTarget // previous active tab
})