this._element = element
this._config = this._getConfig(config)
this._triggerArray = SelectorEngine.find(
- `${SELECTOR_DATA_TOGGLE}[href="#${element.id}"],` +
`${SELECTOR_DATA_TOGGLE}[data-target="#${element.id}"]`
)
targets
.map(element => {
let target
- const targetSelector = getSelectorFromElement(element)
+ const targetSelector = this._getSelectorFromElement(element)
if (targetSelector) {
target = SelectorEngine.findOne(targetSelector)
// Private
+ _getSelectorFromElement(element) {
+ let selector = getSelectorFromElement(element)
+
+ if (!selector) {
+ const hrefAttr = element.getAttribute('href')
+
+ selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null
+ }
+
+ return selector
+ }
+
_getConfig(config) {
config = {
...Default,
}
const getSelector = element => {
- let selector = element.getAttribute('data-target')
+ const selector = element.getAttribute('data-target')
- if (!selector || selector === '#') {
- const hrefAttr = element.getAttribute('href')
-
- selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null
+ if (!selector) {
+ return null
}
return selector
describe('data-api', () => {
it('should show multiple collapsed elements', done => {
fixtureEl.innerHTML = [
- '<a role="button" data-toggle="collapse" class="collapsed" href=".multi"></a>',
+ '<a href="#" role="button" data-toggle="collapse" class="collapsed" data-target=".multi"></a>',
'<div id="collapse1" class="collapse multi"></div>',
'<div id="collapse2" class="collapse multi"></div>'
].join('')
it('should hide multiple collapsed elements', done => {
fixtureEl.innerHTML = [
- '<a role="button" data-toggle="collapse" href=".multi"></a>',
+ '<a href="#" role="button" data-toggle="collapse" data-target=".multi"></a>',
'<div id="collapse1" class="collapse multi show"></div>',
'<div id="collapse2" class="collapse multi show"></div>'
].join('')
fixtureEl.innerHTML = [
'<div id="accordion">',
' <div class="item">',
- ' <a id="linkTrigger" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>',
+ ' <a id="linkTrigger" href="#" data-toggle="collapse" data-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>',
' <div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree" data-parent="#accordion"></div>',
' </div>',
' <div class="item">',
- ' <a id="linkTriggerTwo" data-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>',
+ ' <a id="linkTriggerTwo" href="#" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>',
' <div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo" data-parent="#accordion"></div>',
' </div>',
'</div>'
' <div class="row">',
' <div class="col-lg-6">',
' <div class="item">',
- ' <a id="linkTrigger" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>',
+ ' <a id="linkTrigger" href="#" data-toggle="collapse" data-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>',
' <div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree" data-parent="#accordion"></div>',
' </div>',
' </div>',
' <div class="col-lg-6">',
' <div class="item">',
- ' <a id="linkTriggerTwo" data-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>',
+ ' <a id="linkTriggerTwo" href="#" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>',
' <div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo" data-parent="#accordion"></div>',
' </div>',
' </div>',
fixtureEl.innerHTML = [
'<div id="accordion">',
' <div class="item">',
- ' <a id="linkTrigger" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>',
+ ' <a id="linkTrigger" href="#" data-toggle="collapse" data-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>',
' <div id="collapseOne" data-parent="#accordion" class="collapse" role="tabpanel" aria-labelledby="headingThree">',
' <div id="nestedAccordion">',
' <div class="item">',
- ' <a id="nestedLinkTrigger" data-toggle="collapse" href="#nestedCollapseOne" aria-expanded="false" aria-controls="nestedCollapseOne"></a>',
+ ' <a id="nestedLinkTrigger" href="#" data-toggle="collapse" data-target="#nestedCollapseOne" aria-expanded="false" aria-controls="nestedCollapseOne"></a>',
' <div id="nestedCollapseOne" data-parent="#nestedAccordion" class="collapse" role="tabpanel" aria-labelledby="headingThree"></div>',
' </div>',
' </div>',
' </div>',
' </div>',
' <div class="item">',
- ' <a id="linkTriggerTwo" data-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>',
+ ' <a id="linkTriggerTwo" href="#" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>',
' <div id="collapseTwo" data-parent="#accordion" class="collapse show" role="tabpanel" aria-labelledby="headingTwo"></div>',
' </div>',
'</div>'
it('should add "collapsed" class and set aria-expanded to triggers only when all the targeted collapse are hidden', done => {
fixtureEl.innerHTML = [
- '<a id="trigger1" role="button" data-toggle="collapse" href="#test1"></a>',
- '<a id="trigger2" role="button" data-toggle="collapse" href="#test2"></a>',
- '<a id="trigger3" role="button" data-toggle="collapse" href=".multi"></a>',
+ '<a id="trigger1" href="#" role="button" data-toggle="collapse" data-target="#test1"></a>',
+ '<a id="trigger2" href="#" role="button" data-toggle="collapse" data-target="#test2"></a>',
+ '<a id="trigger3" href="#" role="button" data-toggle="collapse" data-target=".multi"></a>',
'<div id="test1" class="multi"></div>',
'<div id="test2" class="multi"></div>'
].join('')
fixtureEl.innerHTML = [
'<div class="nav">',
' <div class="dropdown" id="testmenu">',
- ' <a class="dropdown-toggle" data-toggle="dropdown" href="#testmenu">Test menu</a>',
+ ' <a href="#" class="dropdown-toggle" data-toggle="dropdown" data-target="#testmenu">Test menu</a>',
' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
+ ' <a href="#" class="dropdown-item" data-target="#sub1">Submenu 1</a>',
' </div>',
' </div>',
'</div>',
it('should remove "show" class if body if tabbing outside of menu, with multiple dropdowns', done => {
fixtureEl.innerHTML = [
'<div class="dropdown">',
- ' <a class="dropdown-toggle" data-toggle="dropdown" href="#testmenu">Test menu</a>',
+ ' <a href="#" class="dropdown-toggle" data-toggle="dropdown" data-target="#testmenu">Test menu</a>',
' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
+ ' <a href="#" class="dropdown-item" data-target="#sub1">Submenu 1</a>',
' </div>',
'</div>',
'<div class="btn-group">',
'<div class="dropdown">',
' <button class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>',
' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
+ ' <a href="#" class="dropdown-item" data-target="#sub1">Submenu 1</a>',
' </div>',
'</div>'
].join('')
'<div class="dropdown">',
' <button class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>',
' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
+ ' <a href="#" class="dropdown-item" data-target="#sub1">Submenu 1</a>',
' <input type="text">',
' <textarea></textarea>',
' </div>',
'<div class="dropdown">',
' <button class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>',
' <div class="dropdown-menu">',
- ' <a class="dropdown-item disabled" href="#sub1">Submenu 1</a>',
+ ' <a href="#" class="dropdown-item disabled" data-target="#sub1">Submenu 1</a>',
' <button class="dropdown-item" type="button" disabled>Disabled button</button>',
' <a id="item1" class="dropdown-item" href="#">Another link</a>',
' </div>',
' <button class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>',
' <div class="dropdown-menu">',
' <button class="dropdown-item d-none" type="button">Hidden button by class</button>',
- ' <a class="dropdown-item" href="#sub1" style="display: none">Hidden link</a>',
- ' <a class="dropdown-item" href="#sub1" style="visibility: hidden">Hidden link</a>',
+ ' <a href="#" class="dropdown-item" data-target="#sub1" style="display: none">Hidden link</a>',
+ ' <a href="#" class="dropdown-item" data-target="#sub1" style="visibility: hidden">Hidden link</a>',
' <a id="item1" class="dropdown-item" href="#">Another link</a>',
' </div>',
'</div>'
'<div class="dropdown">',
' <button class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>',
' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
+ ' <a href="#" class="dropdown-item" data-target="#sub1">Submenu 1</a>',
' <input type="text">',
' <textarea></textarea>',
' </div>',
expect(navEl.getAttribute('id')).not.toEqual(null)
})
- it('should not process element without target', () => {
+ it('should not process element without target and process elements with target inside href attribute', () => {
fixtureEl.innerHTML = [
'<nav id="navigation" class="navbar">',
' <ul class="navbar-nav">',
expect(scrollSpy._targets.length).toEqual(2)
})
+ it('should process element with target in data-target', () => {
+ fixtureEl.innerHTML = [
+ '<nav id="navigation" class="navbar">',
+ ' <ul class="navbar-nav">',
+ ' <li class="nav-item active"><a class="nav-link" id="one-link" href="#">One</a></li>',
+ ' <li class="nav-item"><a class="nav-link" id="two-link" href="#" data-target="#two">Two</a></li>',
+ ' <li class="nav-item"><a class="nav-link" id="three-link" href="#" data-target="#three">Three</a></li>',
+ ' </ul>',
+ '</nav>',
+ '<div id="content" style="height: 200px; overflow-y: auto;">',
+ ' <div id="two" style="height: 300px;"></div>',
+ ' <div id="three" style="height: 10px;"></div>',
+ '</div>'
+ ].join('')
+
+ const scrollSpy = new ScrollSpy(fixtureEl.querySelector('#content'), {
+ target: '#navigation'
+ })
+
+ expect(scrollSpy._targets.length).toEqual(2)
+ })
+
it('should only switch "active" class on current target', done => {
fixtureEl.innerHTML = [
'<div id="root" class="active" style="display: block">',
it('should activate element by tab id', done => {
fixtureEl.innerHTML = [
'<ul class="nav">',
- ' <li><a href="#home" role="tab">Home</a></li>',
- ' <li><a id="triggerProfile" role="tab" href="#profile">Profile</a></li>',
+ ' <li><a href="#" data-target="#home" role="tab">Home</a></li>',
+ ' <li><a href="#" id="triggerProfile" role="tab" data-target="#profile">Profile</a></li>',
'</ul>',
'<ul>',
' <li id="home"></li>',
it('should activate element by tab id in ordered list', done => {
fixtureEl.innerHTML = [
'<ol class="nav nav-pills">',
- ' <li><a href="#home">Home</a></li>',
- ' <li><a id="triggerProfile" href="#profile">Profile</a></li>',
+ ' <li><a href="#" data-target="#home">Home</a></li>',
+ ' <li><a href="#" id="triggerProfile" data-target="#profile">Profile</a></li>',
'</ol>',
'<ol>',
' <li id="home"></li>',
it('should activate element by tab id in nav list', done => {
fixtureEl.innerHTML = [
'<nav class="nav">',
- ' <a href="#home">Home</a>',
- ' <a id="triggerProfile" href="#profile">Profile</a>',
+ ' <a href="#" data-target="#home">Home</a>',
+ ' <a href="#" id="triggerProfile" data-target="#profile">Profile</a>',
'</nav>',
'<nav><div id="home"></div><div id="profile"></div></nav>'
].join('')
it('should activate element by tab id in list group', done => {
fixtureEl.innerHTML = [
'<div class="list-group">',
- ' <a href="#home">Home</a>',
- ' <a id="triggerProfile" href="#profile">Profile</a>',
+ ' <a href="#" data-target="#home">Home</a>',
+ ' <a href="#" id="triggerProfile" data-target="#profile">Profile</a>',
'</div>',
'<nav><div id="home"></div><div id="profile"></div></nav>'
].join('')
it('should not fire shown when tab is already active', done => {
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
- ' <li class="nav-item" role="presentation"><a href="#home" class="nav-link active" role="tab">Home</a></li>',
- ' <li class="nav-item" role="presentation"><a href="#profile" class="nav-link" role="tab">Profile</a></li>',
+ ' <li class="nav-item" role="presentation"><a href="#" data-target="#home" class="nav-link active" role="tab">Home</a></li>',
+ ' <li class="nav-item" role="presentation"><a href="#" data-target="#profile" class="nav-link" role="tab">Profile</a></li>',
'</ul>',
'<div class="tab-content">',
' <div class="tab-pane active" id="home" role="tabpanel"></div>',
it('should not fire shown when tab is disabled', done => {
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
- ' <li class="nav-item" role="presentation"><a href="#home" class="nav-link active" role="tab">Home</a></li>',
- ' <li class="nav-item" role="presentation"><a href="#profile" class="nav-link disabled" role="tab">Profile</a></li>',
+ ' <li class="nav-item" role="presentation"><a href="#" data-target="#home" class="nav-link active" role="tab">Home</a></li>',
+ ' <li class="nav-item" role="presentation"><a href="#" data-target="#profile" class="nav-link disabled" role="tab">Profile</a></li>',
'</ul>',
'<div class="tab-content">',
' <div class="tab-pane active" id="home" role="tabpanel"></div>',
it('show and shown events should reference correct relatedTarget', done => {
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
- ' <li class="nav-item" role="presentation"><a href="#home" class="nav-link active" role="tab">Home</a></li>',
- ' <li class="nav-item" role="presentation"><a id="triggerProfile" href="#profile" class="nav-link" role="tab">Profile</a></li>',
+ ' <li class="nav-item" role="presentation"><a href="#" data-target="#home" class="nav-link active" role="tab">Home</a></li>',
+ ' <li class="nav-item" role="presentation"><a href="#" id="triggerProfile" data-target="#profile" class="nav-link" role="tab">Profile</a></li>',
'</ul>',
'<div class="tab-content">',
' <div class="tab-pane active" id="home" role="tabpanel"></div>',
const secondTab = new Tab(secondTabTrigger)
secondTabTrigger.addEventListener('show.bs.tab', ev => {
- expect(ev.relatedTarget.hash).toEqual('#home')
+ expect(ev.relatedTarget.getAttribute('data-target')).toEqual('#home')
})
secondTabTrigger.addEventListener('shown.bs.tab', ev => {
- expect(ev.relatedTarget.hash).toEqual('#home')
+ expect(ev.relatedTarget.getAttribute('data-target')).toEqual('#home')
expect(secondTabTrigger.getAttribute('aria-selected')).toEqual('true')
expect(fixtureEl.querySelector('a:not(.active)').getAttribute('aria-selected')).toEqual('false')
done()
it('should fire hide and hidden events', done => {
fixtureEl.innerHTML = [
'<ul class="nav">',
- ' <li><a href="#home">Home</a></li>',
- ' <li><a href="#profile">Profile</a></li>',
+ ' <li><a href="#" data-target="#home">Home</a></li>',
+ ' <li><a href="#" data-target="#profile">Profile</a></li>',
'</ul>'
].join('')
triggerList[0].addEventListener('hide.bs.tab', ev => {
hideCalled = true
- expect(ev.relatedTarget.hash).toEqual('#profile')
+ expect(ev.relatedTarget.getAttribute('data-target')).toEqual('#profile')
})
triggerList[0].addEventListener('hidden.bs.tab', ev => {
expect(hideCalled).toEqual(true)
- expect(ev.relatedTarget.hash).toEqual('#profile')
+ expect(ev.relatedTarget.getAttribute('data-target')).toEqual('#profile')
done()
})
it('should not fire hidden when hide is prevented', done => {
fixtureEl.innerHTML = [
'<ul class="nav">',
- ' <li><a href="#home">Home</a></li>',
- ' <li><a href="#profile">Profile</a></li>',
+ ' <li><a href="#" data-target="#home">Home</a></li>',
+ ' <li><a href="#" data-target="#profile">Profile</a></li>',
'</ul>'
].join('')
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
' <li class="nav-item" role="presentation">',
- ' <a class="nav-link nav-tab" href="#profile" role="tab" data-toggle="tab">',
+ ' <a href="#" class="nav-link nav-tab" data-target="#profile" role="tab" data-toggle="tab">',
' <button class="close"><span aria-hidden="true">×</span></button>',
' </a>',
' </li>',
' <li class="nav-item" role="presentation">',
- ' <a id="secondNav" class="nav-link nav-tab" href="#buzz" role="tab" data-toggle="tab">',
+ ' <a href="#" id="secondNav" class="nav-link nav-tab" data-target="#buzz" role="tab" data-toggle="tab">',
' <button class="close"><span aria-hidden="true">×</span></button>',
' </a>',
' </li>',
' <li class="nav-item" role="presentation">',
- ' <a class="nav-link nav-tab" href="#references" role="tab" data-toggle="tab">',
+ ' <a href="#" class="nav-link nav-tab" data-target="#references" role="tab" data-toggle="tab">',
' <button id="btnClose" class="close"><span aria-hidden="true">×</span></button>',
' </a>',
' </li>',
btnCloseEl.addEventListener('click', () => {
const linkEl = btnCloseEl.parentNode
const liEl = linkEl.parentNode
- const tabId = linkEl.getAttribute('href')
+ const tabId = linkEl.getAttribute('data-target')
const tabIdEl = fixtureEl.querySelector(tabId)
liEl.parentNode.removeChild(liEl)
it('should create dynamically a tab', done => {
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
- ' <li class="nav-item" role="presentation"><a href="#home" class="nav-link active" role="tab">Home</a></li>',
- ' <li class="nav-item" role="presentation"><a id="triggerProfile" data-toggle="tab" href="#profile" class="nav-link" role="tab">Profile</a></li>',
+ ' <li class="nav-item" role="presentation"><a href="#" data-target="#home" class="nav-link active" role="tab">Home</a></li>',
+ ' <li class="nav-item" role="presentation"><a href="#" id="triggerProfile" data-toggle="tab" data-target="#profile" class="nav-link" role="tab">Profile</a></li>',
'</ul>',
'<div class="tab-content">',
' <div class="tab-pane active" id="home" role="tabpanel"></div>',
it('selected tab should deactivate previous selected link in dropdown', () => {
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs">',
- ' <li class="nav-item"><a class="nav-link" href="#home" data-toggle="tab">Home</a></li>',
- ' <li class="nav-item"><a class="nav-link" href="#profile" data-toggle="tab">Profile</a></li>',
+ ' <li class="nav-item"><a href="#" class="nav-link" data-target="#home" data-toggle="tab">Home</a></li>',
+ ' <li class="nav-item"><a href="#" class="nav-link" data-target="#profile" data-toggle="tab">Profile</a></li>',
' <li class="nav-item dropdown">',
' <a class="nav-link dropdown-toggle active" data-toggle="dropdown" href="#">Dropdown</a>',
' <div class="dropdown-menu">',
- ' <a class="dropdown-item active" href="#dropdown1" id="dropdown1-tab" data-toggle="tab">@fat</a>',
- ' <a class="dropdown-item" href="#dropdown2" id="dropdown2-tab" data-toggle="tab">@mdo</a>',
+ ' <a href="#" class="dropdown-item active" data-target="#dropdown1" id="dropdown1-tab" data-toggle="tab">@fat</a>',
+ ' <a href="#" class="dropdown-item" data-target="#dropdown2" id="dropdown2-tab" data-toggle="tab">@mdo</a>',
' </div>',
' </li>',
'</ul>'
it('should handle nested tabs', done => {
fixtureEl.innerHTML = [
'<nav class="nav nav-tabs" role="tablist">',
- ' <a id="tab1" href="#x-tab1" class="nav-link" data-toggle="tab" role="tab" aria-controls="x-tab1">Tab 1</a>',
- ' <a href="#x-tab2" class="nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab2" aria-selected="true">Tab 2</a>',
- ' <a href="#x-tab3" class="nav-link" data-toggle="tab" role="tab" aria-controls="x-tab3">Tab 3</a>',
+ ' <a href="#" id="tab1" data-target="#x-tab1" class="nav-link" data-toggle="tab" role="tab" aria-controls="x-tab1">Tab 1</a>',
+ ' <a href="#" data-target="#x-tab2" class="nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab2" aria-selected="true">Tab 2</a>',
+ ' <a href="#" data-target="#x-tab3" class="nav-link" data-toggle="tab" role="tab" aria-controls="x-tab3">Tab 3</a>',
'</nav>',
'<div class="tab-content">',
' <div class="tab-pane" id="x-tab1" role="tabpanel">',
' <nav class="nav nav-tabs" role="tablist">',
- ' <a href="#nested-tab1" class="nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab1" aria-selected="true">Nested Tab 1</a>',
- ' <a id="tabNested2" href="#nested-tab2" class="nav-link" data-toggle="tab" role="tab" aria-controls="x-profile">Nested Tab2</a>',
+ ' <a href="#" data-target="#nested-tab1" class="nav-link active" data-toggle="tab" role="tab" aria-controls="x-tab1" aria-selected="true">Nested Tab 1</a>',
+ ' <a href="#" id="tabNested2" data-target="#nested-tab2" class="nav-link" data-toggle="tab" role="tab" aria-controls="x-profile">Nested Tab2</a>',
' </nav>',
' <div class="tab-content">',
' <div class="tab-pane active" id="nested-tab1" role="tabpanel">Nested Tab1 Content</div>',
it('should not remove fade class if no active pane is present', done => {
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
- ' <li class="nav-item" role="presentation"><a id="tab-home" href="#home" class="nav-link" data-toggle="tab" role="tab">Home</a></li>',
- ' <li class="nav-item" role="presentation"><a id="tab-profile" href="#profile" class="nav-link" data-toggle="tab" role="tab">Profile</a></li>',
+ ' <li class="nav-item" role="presentation"><a href="#" id="tab-home" data-target="#home" class="nav-link" data-toggle="tab" role="tab">Home</a></li>',
+ ' <li class="nav-item" role="presentation"><a href="#" id="tab-profile" data-target="#profile" class="nav-link" data-toggle="tab" role="tab">Profile</a></li>',
'</ul>',
'<div class="tab-content">',
' <div class="tab-pane fade" id="home" role="tabpanel"></div>',
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
' <li class="nav-item" role="presentation">',
- ' <a class="nav-link nav-tab" href="#home" role="tab" data-toggle="tab">Home</a>',
+ ' <a href="#" class="nav-link nav-tab" data-target="#home" role="tab" data-toggle="tab">Home</a>',
' </li>',
' <li class="nav-item" role="presentation">',
- ' <a id="secondNav" class="nav-link nav-tab" href="#profile" role="tab" data-toggle="tab">Profile</a>',
+ ' <a href="#" id="secondNav" class="nav-link nav-tab" data-target="#profile" role="tab" data-toggle="tab">Profile</a>',
' </li>',
'</ul>',
'<div class="tab-content">',
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
' <li class="nav-item" role="presentation">',
- ' <a class="nav-link nav-tab" href="#home" role="tab" data-toggle="tab">Home</a>',
+ ' <a href="#" class="nav-link nav-tab" data-target="#home" role="tab" data-toggle="tab">Home</a>',
' </li>',
' <li class="nav-item" role="presentation">',
- ' <a id="secondNav" class="nav-link nav-tab" href="#profile" role="tab" data-toggle="tab">Profile</a>',
+ ' <a href="#" id="secondNav" class="nav-link nav-tab" data-target="#profile" role="tab" data-toggle="tab">Profile</a>',
' </li>',
'</ul>',
'<div class="tab-content">',
expect(Util.getSelectorFromElement(testEl)).toEqual('.target')
})
- it('should get selector from href if no data-target set', () => {
- fixtureEl.innerHTML = [
- '<a id="test" href=".target"></a>',
- '<div class="target"></div>'
- ].join('')
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getSelectorFromElement(testEl)).toEqual('.target')
- })
-
- it('should get selector from href if data-target equal to #', () => {
- fixtureEl.innerHTML = [
- '<a id="test" data-target="#" href=".target"></a>',
- '<div class="target"></div>'
- ].join('')
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getSelectorFromElement(testEl)).toEqual('.target')
- })
-
- it('should return null if selector not found', () => {
- fixtureEl.innerHTML = '<a id="test" href=".target"></a>'
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getSelectorFromElement(testEl)).toBeNull()
- })
-
it('should return null if no selector', () => {
fixtureEl.innerHTML = '<div></div>'
expect(Util.getElementFromSelector(testEl)).toEqual(fixtureEl.querySelector('.target'))
})
- it('should get element from href if no data-target set', () => {
- fixtureEl.innerHTML = [
- '<a id="test" href=".target"></a>',
- '<div class="target"></div>'
- ].join('')
-
- const testEl = fixtureEl.querySelector('#test')
-
- expect(Util.getElementFromSelector(testEl)).toEqual(fixtureEl.querySelector('.target'))
- })
-
it('should return null if element not found', () => {
- fixtureEl.innerHTML = '<a id="test" href=".target"></a>'
+ fixtureEl.innerHTML = '<a id="test" data-target=".target"></a>'
const testEl = fixtureEl.querySelector('#test')
<img src="https://i.imgur.com/Nm7xoti.jpg" alt="Third slide">
</div>
</div>
- <a class="carousel-control-prev" href="#carousel-example-generic" role="button" data-slide="prev">
+ <a href="#" class="carousel-control-prev" data-target="#carousel-example-generic" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
- <a class="carousel-control-next" href="#carousel-example-generic" role="button" data-slide="next">
+ <a href="#" class="carousel-control-next" data-target="#carousel-example-generic" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
<div class="card" role="presentation">
<div class="card-header" role="tab" id="headingOne">
<h5 class="mb-0">
- <a data-toggle="collapse" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
+ <a href="#" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Collapsible Group Item #1
</a>
</h5>
<div class="card" role="presentation">
<div class="card-header" role="tab" id="headingTwo">
<h5 class="mb-0">
- <a class="collapsed" data-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
+ <a href="#" class="collapsed" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Collapsible Group Item #2
</a>
</h5>
<div class="card" role="presentation">
<div class="card-header" role="tab" id="headingThree">
<h5 class="mb-0">
- <a class="collapsed" data-toggle="collapse" href="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
+ <a href="#" class="collapsed" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
Collapsible Group Item #3
</a>
</h5>
<div class="card" role="presentation">
<div class="card-header" role="tab" id="headingFour">
<h5 class="mb-0">
- <a class="collapsed" data-toggle="collapse" href="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
+ <a href="#" class="collapsed" data-toggle="collapse" data-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
Collapsible Group Item with XSS in data-parent
</a>
</h5>
<div class="card" role="presentation">
<div class="card-header" role="tab" id="headingOne">
<h5 class="mb-0">
- <a data-toggle="collapse" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
+ <a href="#" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Collapsible Group Item #1
</a>
</h5>
<div class="card" role="presentation">
<div class="card-header" role="tab" id="headingTwo">
<h5 class="mb-0">
- <a class="collapsed" data-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
+ <a href="#" class="collapsed" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Collapsible Group Item #2
</a>
</h5>
<div class="card" role="presentation">
<div class="card-header" role="tab" id="headingThree">
<h5 class="mb-0">
- <a class="collapsed" data-toggle="collapse" href="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
+ <a href="#" class="collapsed" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
Collapsible Group Item #3
</a>
</h5>
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item" role="presentation">
- <a class="nav-link active" data-toggle="tab" href="#home" role="tab">Home</a>
+ <a href="#" class="nav-link active" data-toggle="tab" data-target="#home" role="tab">Home</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#profile" role="tab">Profile</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#profile" role="tab">Profile</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#fat" role="tab">@fat</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#fat" role="tab">@fat</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#mdo" role="tab">@mdo</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#mdo" role="tab">@mdo</a>
</li>
</ul>
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item" role="presentation">
- <a class="nav-link active" data-toggle="tab" href="#home2" role="tab">Home</a>
+ <a href="#" class="nav-link active" data-toggle="tab" data-target="#home2" role="tab">Home</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#profile2" role="tab">Profile</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#profile2" role="tab">Profile</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#fat2" role="tab">@fat</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#fat2" role="tab">@fat</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#mdo2" role="tab">@mdo</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#mdo2" role="tab">@mdo</a>
</li>
</ul>
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#home3" role="tab">Home</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#home3" role="tab">Home</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#profile3" role="tab">Profile</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#profile3" role="tab">Profile</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#fat3" role="tab">@fat</a>
+ <a class="nav-link" data-toggle="tab" data-target="#fat3" role="tab">@fat</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#mdo3" role="tab">@mdo</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#mdo3" role="tab">@mdo</a>
</li>
</ul>
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#home4" role="tab">Home</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#home4" role="tab">Home</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#profile4" role="tab">Profile</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#profile4" role="tab">Profile</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#fat4" role="tab">@fat</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#fat4" role="tab">@fat</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" data-toggle="tab" href="#mdo4" role="tab">@mdo</a>
+ <a href="#" class="nav-link" data-toggle="tab" data-target="#mdo4" role="tab">@mdo</a>
</li>
</ul>
<h4>Tabs with nav (with fade)</h4>
<nav class="nav nav-pills">
- <a class="nav-link nav-item active" data-toggle="tab" href="#home5">Home</a>
- <a class="nav-link nav-item" data-toggle="tab" href="#profile5">Profile</a>
+ <a href="#" class="nav-link nav-item active" data-toggle="tab" data-target="#home5">Home</a>
+ <a href="#" class="nav-link nav-item" data-toggle="tab" data-target="#profile5">Profile</a>
<div class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="dropdown5" data-toggle="dropdown" aria-expanded="false">Dropdown</a>
<ul class="dropdown-menu" aria-labelledby="dropdown5">
- <li><a class="dropdown-item" data-toggle="tab" href="#fat5">@fat</a></li>
- <li><a class="dropdown-item" data-toggle="tab" href="#mdo5">@mdo</a></li>
+ <li><a href="#" class="dropdown-item" data-toggle="tab" data-target="#fat5">@fat</a></li>
+ <li><a href="#" class="dropdown-item" data-toggle="tab" data-target="#mdo5">@mdo</a></li>
</ul>
</div>
<a class="nav-link nav-item disabled" href="#">Disabled</a>
<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-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-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-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-toggle="tab" href="#list-settings" role="tab" aria-controls="list-settings">Settings</a>
+ <a href="#" class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="tab" data-target="#list-home" role="tab" aria-controls="list-home">Home</a>
+ <a href="#" class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="tab" data-target="#list-profile" role="tab" aria-controls="list-profile">Profile</a>
+ <a href="#" class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="tab" data-target="#list-messages" role="tab" aria-controls="list-messages">Messages</a>
+ <a href="#" class="list-group-item list-group-item-action" id="list-settings-list" data-toggle="tab" data-target="#list-settings" role="tab" aria-controls="list-settings">Settings</a>
</div>
</div>
<div class="col-8">
Carousels don't automatically normalize slide dimensions. As such, you may need to use additional utilities or custom styles to appropriately size content. While carousels support previous/next controls and indicators, they're not explicitly required. Add and customize as you see fit.
-**The `.active` class needs to be added to one of the slides** otherwise the carousel will not be visible. Also be sure to set a unique id on the `.carousel` for optional controls, especially if you're using multiple carousels on a single page. Control and indicator elements must have a `data-target` attribute (or `href` for links) that matches the id of the `.carousel` element.
+**The `.active` class needs to be added to one of the slides** otherwise the carousel will not be visible. Also be sure to set a unique id on the `.carousel` for optional controls, especially if you're using multiple carousels on a single page. Control and indicator elements must have a `data-target` attribute that matches the id of the `.carousel` element.
### Slides only
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#333" background="#555" text="Third slide" >}}
</div>
</div>
- <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
+ <a href="#" class="carousel-control-prev" data-target="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
- <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
+ <a href="#" class="carousel-control-next" data-target="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#333" background="#555" text="Third slide" >}}
</div>
</div>
- <a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
+ <a href="#" class="carousel-control-prev" data-target="#carouselExampleIndicators" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
- <a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
+ <a href="#" class="carousel-control-next" data-target="#carouselExampleIndicators" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
- <a class="carousel-control-prev" href="#carouselExampleCaptions" role="button" data-slide="prev">
+ <a href="#" class="carousel-control-prev" data-target="#carouselExampleCaptions" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
- <a class="carousel-control-next" href="#carouselExampleCaptions" role="button" data-slide="next">
+ <a href="#" class="carousel-control-next" data-target="#carouselExampleCaptions" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#333" background="#555" text="Third slide" >}}
</div>
</div>
- <a class="carousel-control-prev" href="#carouselExampleFade" role="button" data-slide="prev">
+ <a href="#" class="carousel-control-prev" data-target="#carouselExampleFade" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
- <a class="carousel-control-next" href="#carouselExampleFade" role="button" data-slide="next">
+ <a href="#" class="carousel-control-next" data-target="#carouselExampleFade" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#333" background="#555" text="Third slide" >}}
</div>
</div>
- <a class="carousel-control-prev" href="#carouselExampleInterval" role="button" data-slide="prev">
+ <a href="#" class="carousel-control-prev" data-target="#carouselExampleInterval" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
- <a class="carousel-control-next" href="#carouselExampleInterval" role="button" data-slide="next">
+ <a href="#" class="carousel-control-next" data-target="#carouselExampleInterval" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
- `.collapsing` is applied during transitions
- `.collapse.show` shows content
-You can use a link with the `href` attribute, or a button with the `data-target` attribute. In both cases, the `data-toggle="collapse"` is required.
+You can use any element with the `data-target` attribute. In both cases, the `data-toggle="collapse"` is required.
{{< example >}}
<p>
- <a class="btn btn-primary" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
- Link with href
+ <a href="#" class="btn btn-primary" data-toggle="collapse" data-target="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
+ Link with data-target
</a>
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
Button with data-target
## Multiple targets
-A `<button>` or `<a>` can show and hide multiple elements by referencing them with a selector in its `href` or `data-target` attribute.
-Multiple `<button>` or `<a>` can show and hide an element if they each reference it with their `href` or `data-target` attribute
+Any element can show and hide multiple elements by referencing them with a selector in its `data-target` attribute.
+Multiple `<button>` or `<a>` can show and hide an element if they each reference it with their `data-target` attribute
{{< example >}}
<p>
- <a class="btn btn-primary" data-toggle="collapse" href="#multiCollapseExample1" role="button" aria-expanded="false" aria-controls="multiCollapseExample1">Toggle first element</a>
+ <a href="#" class="btn btn-primary" data-toggle="collapse" data-target="#multiCollapseExample1" role="button" aria-expanded="false" aria-controls="multiCollapseExample1">Toggle first element</a>
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#multiCollapseExample2" aria-expanded="false" aria-controls="multiCollapseExample2">Toggle second element</button>
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target=".multi-collapse" aria-expanded="false" aria-controls="multiCollapseExample1 multiCollapseExample2">Toggle both elements</button>
</p>
<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-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-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-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-toggle="tab" href="#list-settings" role="tab" aria-controls="list-settings">Settings</a>
+ <a href="#" class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="tab" data-target="#list-home" role="tab" aria-controls="list-home">Home</a>
+ <a href="#" class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="tab" data-target="#list-profile" role="tab" aria-controls="list-profile">Profile</a>
+ <a href="#" class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="tab" data-target="#list-messages" role="tab" aria-controls="list-messages">Messages</a>
+ <a href="#" class="list-group-item list-group-item-action" id="list-settings-list" data-toggle="tab" data-target="#list-settings" role="tab" aria-controls="list-settings">Settings</a>
</div>
</div>
<div class="col-8">
<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-toggle="list" href="#list-home" role="tab" aria-controls="home">Home</a>
- <a class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="list" href="#list-profile" role="tab" aria-controls="profile">Profile</a>
- <a class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="list" href="#list-messages" role="tab" aria-controls="messages">Messages</a>
- <a class="list-group-item list-group-item-action" id="list-settings-list" data-toggle="list" href="#list-settings" role="tab" aria-controls="settings">Settings</a>
+ <a href="#" class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="list" data-target="#list-home" role="tab" aria-controls="home">Home</a>
+ <a href="#" class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="list" data-target="#list-profile" role="tab" aria-controls="profile">Profile</a>
+ <a href="#" class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="list" data-target="#list-messages" role="tab" aria-controls="messages">Messages</a>
+ <a href="#" class="list-group-item list-group-item-action" id="list-settings-list" data-toggle="list" data-target="#list-settings" role="tab" aria-controls="settings">Settings</a>
</div>
</div>
<div class="col-8">
{{< highlight html >}}
<!-- List group -->
<div class="list-group" id="myList" role="tablist">
- <a class="list-group-item list-group-item-action active" data-toggle="list" href="#home" role="tab">Home</a>
- <a class="list-group-item list-group-item-action" data-toggle="list" href="#profile" role="tab">Profile</a>
- <a class="list-group-item list-group-item-action" data-toggle="list" href="#messages" role="tab">Messages</a>
- <a class="list-group-item list-group-item-action" data-toggle="list" href="#settings" role="tab">Settings</a>
+ <a href="#" class="list-group-item list-group-item-action active" data-toggle="list" data-target="#home" role="tab">Home</a>
+ <a href="#" class="list-group-item list-group-item-action" data-toggle="list" data-target="#profile" role="tab">Profile</a>
+ <a href="#" class="list-group-item list-group-item-action" data-toggle="list" data-target="#messages" role="tab">Messages</a>
+ <a href="#" class="list-group-item list-group-item-action" data-toggle="list" data-target="#settings" role="tab">Settings</a>
</div>
<!-- Tab panes -->
You can activate individual list item in several ways:
{{< highlight js >}}
-var triggerEl = document.querySelector('#myTab a[href="#profile"]')
+var triggerEl = document.querySelector('#myTab a[data-target="#profile"]')
bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name
var triggerFirstTabEl = document.querySelector('#myTab li:first-child a')
#### constructor
-Activates a list item element and content container. Tab should have either a `data-target` or an `href` targeting a container node in the DOM.
+Activates a list item element and content container. Tab should have either a `data-target` targeting a container node in the DOM.
{{< highlight html >}}
<div class="list-group" id="myList" role="tablist">
- <a class="list-group-item list-group-item-action active" data-toggle="list" href="#home" role="tab">Home</a>
- <a class="list-group-item list-group-item-action" data-toggle="list" href="#profile" role="tab">Profile</a>
- <a class="list-group-item list-group-item-action" data-toggle="list" href="#messages" role="tab">Messages</a>
- <a class="list-group-item list-group-item-action" data-toggle="list" href="#settings" role="tab">Settings</a>
+ <a href="#" class="list-group-item list-group-item-action active" data-toggle="list" data-target="#home" role="tab">Home</a>
+ <a href="#" class="list-group-item list-group-item-action" data-toggle="list" data-target="#profile" role="tab">Profile</a>
+ <a href="#" class="list-group-item list-group-item-action" data-toggle="list" data-target="#messages" role="tab">Messages</a>
+ <a href="#" class="list-group-item list-group-item-action" data-toggle="list" data-target="#settings" role="tab">Settings</a>
</div>
<div class="tab-content">
### Via data attributes
-Activate a modal without writing JavaScript. Set `data-toggle="modal"` on a controller element, like a button, along with a `data-target="#foo"` or `href="#foo"` to target a specific modal to toggle.
+Activate a modal without writing JavaScript. Set `data-toggle="modal"` on a controller element, like a button, along with a `data-target="#foo"` to target a specific modal to toggle.
{{< highlight html >}}
<button type="button" data-toggle="modal" data-target="#myModal">Launch modal</button>
<div class="bd-example">
<ul class="nav nav-tabs mb-3" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
- <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
+ <a href="#" class="nav-link active" id="home-tab" data-toggle="tab" data-target="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
+ <a href="#" class="nav-link" id="profile-tab" data-toggle="tab" data-target="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
+ <a href="#" class="nav-link" id="contact-tab" data-toggle="tab" data-target="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
{{< highlight html >}}
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
- <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
+ <a href="#" class="nav-link active" id="home-tab" data-toggle="tab" data-target="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
+ <a href="#" class="nav-link" id="profile-tab" data-toggle="tab" data-target="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
+ <a href="#" class="nav-link" id="contact-tab" data-toggle="tab" data-target="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="bd-example">
<nav>
<div class="nav nav-tabs mb-3" id="nav-tab" role="tablist">
- <a class="nav-link active" id="nav-home-tab" data-toggle="tab" href="#nav-home" role="tab" aria-controls="nav-home" aria-selected="true">Home</a>
- <a class="nav-link" id="nav-profile-tab" data-toggle="tab" href="#nav-profile" role="tab" aria-controls="nav-profile" aria-selected="false">Profile</a>
- <a class="nav-link" id="nav-contact-tab" data-toggle="tab" href="#nav-contact" role="tab" aria-controls="nav-contact" aria-selected="false">Contact</a>
+ <a href="#" class="nav-link active" id="nav-home-tab" data-toggle="tab" data-target="#nav-home" role="tab" aria-controls="nav-home" aria-selected="true">Home</a>
+ <a href="#" class="nav-link" id="nav-profile-tab" data-toggle="tab" data-target="#nav-profile" role="tab" aria-controls="nav-profile" aria-selected="false">Profile</a>
+ <a href="#" class="nav-link" id="nav-contact-tab" data-toggle="tab" data-target="#nav-contact" role="tab" aria-controls="nav-contact" aria-selected="false">Contact</a>
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
{{< highlight html >}}
<nav>
<div class="nav nav-tabs" id="nav-tab" role="tablist">
- <a class="nav-link active" id="nav-home-tab" data-toggle="tab" href="#nav-home" role="tab" aria-controls="nav-home" aria-selected="true">Home</a>
- <a class="nav-link" id="nav-profile-tab" data-toggle="tab" href="#nav-profile" role="tab" aria-controls="nav-profile" aria-selected="false">Profile</a>
- <a class="nav-link" id="nav-contact-tab" data-toggle="tab" href="#nav-contact" role="tab" aria-controls="nav-contact" aria-selected="false">Contact</a>
+ <a href="#" class="nav-link active" id="nav-home-tab" data-toggle="tab" data-target="#nav-home" role="tab" aria-controls="nav-home" aria-selected="true">Home</a>
+ <a href="#" class="nav-link" id="nav-profile-tab" data-toggle="tab" data-target="#nav-profile" role="tab" aria-controls="nav-profile" aria-selected="false">Profile</a>
+ <a href="#" class="nav-link" id="nav-contact-tab" data-toggle="tab" data-target="#nav-contact" role="tab" aria-controls="nav-contact" aria-selected="false">Contact</a>
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
<div class="bd-example">
<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
<li class="nav-item" role="presentation">
- <a class="nav-link active" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true">Home</a>
+ <a href="#" class="nav-link active" id="pills-home-tab" data-toggle="pill" data-target="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true">Home</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-profile" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</a>
+ <a href="#" class="nav-link" id="pills-profile-tab" data-toggle="pill" data-target="#pills-profile" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="pills-contact-tab" data-toggle="pill" href="#pills-contact" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</a>
+ <a href="#" class="nav-link" id="pills-contact-tab" data-toggle="pill" data-target="#pills-contact" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</a>
</li>
</ul>
<div class="tab-content" id="pills-tabContent">
{{< highlight html >}}
<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
<li class="nav-item" role="presentation">
- <a class="nav-link active" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true">Home</a>
+ <a href="#" class="nav-link active" id="pills-home-tab" data-toggle="pill" data-target="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true">Home</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="pills-profile-tab" data-toggle="pill" href="#pills-profile" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</a>
+ <a href="#" class="nav-link" id="pills-profile-tab" data-toggle="pill" data-target="#pills-profile" role="tab" aria-controls="pills-profile" aria-selected="false">Profile</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="pills-contact-tab" data-toggle="pill" href="#pills-contact" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</a>
+ <a href="#" class="nav-link" id="pills-contact-tab" data-toggle="pill" data-target="#pills-contact" role="tab" aria-controls="pills-contact" aria-selected="false">Contact</a>
</li>
</ul>
<div class="tab-content" id="pills-tabContent">
<div class="row">
<div class="col-3">
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
- <a class="nav-link active" id="v-pills-home-tab" data-toggle="pill" href="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Home</a>
- <a class="nav-link" id="v-pills-profile-tab" data-toggle="pill" href="#v-pills-profile" role="tab" aria-controls="v-pills-profile" aria-selected="false">Profile</a>
- <a class="nav-link" id="v-pills-messages-tab" data-toggle="pill" href="#v-pills-messages" role="tab" aria-controls="v-pills-messages" aria-selected="false">Messages</a>
- <a class="nav-link" id="v-pills-settings-tab" data-toggle="pill" href="#v-pills-settings" role="tab" aria-controls="v-pills-settings" aria-selected="false">Settings</a>
+ <a href="#" class="nav-link active" id="v-pills-home-tab" data-toggle="pill" data-target="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Home</a>
+ <a href="#" class="nav-link" id="v-pills-profile-tab" data-toggle="pill" data-target="#v-pills-profile" role="tab" aria-controls="v-pills-profile" aria-selected="false">Profile</a>
+ <a href="#" class="nav-link" id="v-pills-messages-tab" data-toggle="pill" data-target="#v-pills-messages" role="tab" aria-controls="v-pills-messages" aria-selected="false">Messages</a>
+ <a href="#" class="nav-link" id="v-pills-settings-tab" data-toggle="pill" data-target="#v-pills-settings" role="tab" aria-controls="v-pills-settings" aria-selected="false">Settings</a>
</div>
</div>
<div class="col-9">
<div class="row">
<div class="col-3">
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
- <a class="nav-link active" id="v-pills-home-tab" data-toggle="pill" href="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Home</a>
- <a class="nav-link" id="v-pills-profile-tab" data-toggle="pill" href="#v-pills-profile" role="tab" aria-controls="v-pills-profile" aria-selected="false">Profile</a>
- <a class="nav-link" id="v-pills-messages-tab" data-toggle="pill" href="#v-pills-messages" role="tab" aria-controls="v-pills-messages" aria-selected="false">Messages</a>
- <a class="nav-link" id="v-pills-settings-tab" data-toggle="pill" href="#v-pills-settings" role="tab" aria-controls="v-pills-settings" aria-selected="false">Settings</a>
+ <a href="#" class="nav-link active" id="v-pills-home-tab" data-toggle="pill" data-target="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Home</a>
+ <a href="#" class="nav-link" id="v-pills-profile-tab" data-toggle="pill" data-target="#v-pills-profile" role="tab" aria-controls="v-pills-profile" aria-selected="false">Profile</a>
+ <a href="#" class="nav-link" id="v-pills-messages-tab" data-toggle="pill" data-target="#v-pills-messages" role="tab" aria-controls="v-pills-messages" aria-selected="false">Messages</a>
+ <a href="#" class="nav-link" id="v-pills-settings-tab" data-toggle="pill" data-target="#v-pills-settings" role="tab" aria-controls="v-pills-settings" aria-selected="false">Settings</a>
</div>
</div>
<div class="col-9">
<!-- Nav tabs -->
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
- <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
+ <a href="#" class="nav-link active" id="home-tab" data-toggle="tab" data-target="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
+ <a href="#" class="nav-link" id="profile-tab" data-toggle="tab" data-target="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="messages-tab" data-toggle="tab" href="#messages" role="tab" aria-controls="messages" aria-selected="false">Messages</a>
+ <a href="#" class="nav-link" id="messages-tab" data-toggle="tab" data-target="#messages" role="tab" aria-controls="messages" aria-selected="false">Messages</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="settings-tab" data-toggle="tab" href="#settings" role="tab" aria-controls="settings" aria-selected="false">Settings</a>
+ <a href="#" class="nav-link" id="settings-tab" data-toggle="tab" data-target="#settings" role="tab" aria-controls="settings" aria-selected="false">Settings</a>
</li>
</ul>
You can activate individual tabs in several ways:
{{< highlight js >}}
-var triggerEl = document.querySelector('#myTab a[href="#profile"]')
+var triggerEl = document.querySelector('#myTab a[data-target="#profile"]')
bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name
var triggerFirstTabEl = document.querySelector('#myTab li:first-child a')
#### constructor
-Activates a tab element and content container. Tab should have either a `data-target` or an `href` targeting a container node in the DOM.
+Activates a tab element and content container. Tab should have either a `data-target` targeting a container node in the DOM.
{{< highlight html >}}
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
- <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
+ <a href="#" class="nav-link active" id="home-tab" data-toggle="tab" data-target="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
+ <a href="#" class="nav-link" id="profile-tab" data-toggle="tab" data-target="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="messages-tab" data-toggle="tab" href="#messages" role="tab" aria-controls="messages" aria-selected="false">Messages</a>
+ <a href="#" class="nav-link" id="messages-tab" data-toggle="tab" data-target="#messages" role="tab" aria-controls="messages" aria-selected="false">Messages</a>
</li>
<li class="nav-item" role="presentation">
- <a class="nav-link" id="settings-tab" data-toggle="tab" href="#settings" role="tab" aria-controls="settings" aria-selected="false">Settings</a>
+ <a href="#" class="nav-link" id="settings-tab" data-toggle="tab" data-target="#settings" role="tab" aria-controls="settings" aria-selected="false">Settings</a>
</li>
</ul>
- Dropped jQuery dependency and rewrote plugins to be in regular JavaScript.
- Removed underscore from public static methods like `_getInstance()` → `getInstance()`.
+- Drop the use of `href` attributes to target element, except for our Scrollspy.
## Color system
{{- $is_active_group := eq $.Page.Params.group $group_slug }}
<li class="my-1{{ if $is_active_group }} active{{ end }}">
- <a class="d-inline-flex align-items-center rounded{{ if not $is_active_group }} collapsed{{ end }}" data-toggle="collapse" href="#{{ $group_slug }}-collapse" role="button" aria-expanded="{{ $is_active_group }}"{{ if $is_active_group }} aria-current="true"{{ end }}>
+ <a href="#" class="d-inline-flex align-items-center rounded{{ if not $is_active_group }} collapsed{{ end }}" data-toggle="collapse" data-target="#{{ $group_slug }}-collapse" role="button" aria-expanded="{{ $is_active_group }}"{{ if $is_active_group }} aria-current="true"{{ end }}>
{{ $group.title }}
</a>