将多个原版 JavaScript 选项卡添加到同一页面



使用以下代码的变体,我能够成功添加一组Vanilla JavaScript选项卡。

然而,我如何使用HTML中的相同类将多组JavaScript选项卡添加到一个页面。

我很难使用 JavaScript 为选项卡选择器和选项卡内容区域创建唯一的动态 ID。正如您在 https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-1/tabs.html 中看到的,这些唯一 ID 是可访问标签所必需的。

var accessibleTabsContainers = document.querySelectorAll('.accessible-tabs-container');
var tabSelector = document.querySelectorAll('.tab-selectors > li');
var tabContent = document.querySelectorAll('.tab-contents > div');
var largeRandNumber = Math.floor((Math.random() * 1000) + 1000);
accessibleTabsContainers.forEach(function(elem, indexAccessibleTabContainer) {
elem.setAttribute('data-id', indexAccessibleTabContainer);

tabSelector.forEach(function(singleTabSelector, i) {

var ariaControlTabContent = 'tab-content-' + largeRandNumber + '-' + i + '_' + indexAccessibleTabContainer;
var tabSelectorId = 'tab-selector-' + largeRandNumber + '-' + i + '_' + indexAccessibleTabContainer;
singleTabSelector.setAttribute('data-id', i);
singleTabSelector.setAttribute('id', tabSelectorId);
singleTabSelector.setAttribute('aria-controls', ariaControlTabContent);
tabContent[i].setAttribute('data-id', i);
tabContent[i].setAttribute('tabindex', 0);
tabContent[i].setAttribute('role', 'tabpanel');
tabContent[i].setAttribute('id', ariaControlTabContent);
tabContent[i].setAttribute('aria-labeledby', tabSelectorId);
if(i === 0) {
tabSelector[i].setAttribute('aria-pressed', 'true');
} else {
tabSelector[i].setAttribute('aria-pressed', 'false');
tabSelector[i].setAttribute('tabindex', -1);
}
});
});  
function onTabSelectorClick(e) {

accessibleTabsContainers.forEach(function(accessibleTabsContainer, indexAccessibleTabContainer) {   
var tabSelectorSelected = e.target;
var accessibleTabsContainerSelected = tabSelectorSelected.parentElement.parentElement;

if(!tabSelectorSelected.classList.contains('active-tab-selector')) {

var tabSelectorSelectedFromContainer = accessibleTabsContainerSelected.querySelectorAll('.tab-contents > div');
console.log(tabSelectorSelectedFromContainer);
tabSelector.forEach(function(singleTabSelected, i) {
if(tabSelectorSelected.getAttribute('data-id') === tabContent[i].getAttribute('data-id')) {        
tabContent[i].classList.add('tab-content-active');
} else {
tabSelector[i].classList.remove('active-tab-selector');
tabSelector[i].setAttribute('aria-pressed', 'false');
tabSelector[i].setAttribute('aria-selected', 'false');
tabSelector[i].setAttribute('tabindex', -1);
tabContent[i].classList.remove('tab-content-active');
}      
});
tabSelectorSelected.classList.add('active-tab-selector');
tabSelectorSelected.setAttribute('aria-pressed', 'true');        
tabSelectorSelected.setAttribute('aria-selected', 'true');
tabSelectorSelected.removeAttribute('tabindex'); 
}
});
}
tabSelector.forEach(function(tabSelector) {
tabSelector.addEventListener('click', onTabSelectorClick);
});
.wrapper {
max-width: 960px;
margin: 0 auto;
}
.tab-selectors {
display: inline-block;
}
.tab-selectors > li {
padding: 10px;
}
.tab-selectors > .active-tab-selector {
border: 1px solid #f00; 
}
.tab-content {
display: inline-block;
}
.tab-contents > div {
padding: 10px;
border: 2px solid #000;
height: 150px;
width: 150px;
display: none;
}
.tab-contents > .tab-content-active {
display: block;
}
<div class="wrapper">
<h1>Accessible Tabs using Vanilla JavaScript</h1>

<div class="accessible-tabs-container">  

<ul role="tablist" aria-lable="Tabs Example" class="tab-selectors">
<li class="active-tab-selector">Tab Selector 1</li>
<li>Tab Selector 2</li>
<li>Tab Selector 3</li>
</ul>  
<div class="tab-contents">
<div class="tab-content-active">
Tab Content 1
</div>  
<div>
Tab Content 2
</div>  
<div>
Tab Content 3
</div>
</div> 

</div>


<div class="accessible-tabs-container">  

<ul role="tablist" aria-lable="Tabs Example" class="tab-selectors">
<li class="active-tab-selector">Tab Selector 1</li>
<li>Tab Selector 2</li>
<li>Tab Selector 3</li>
</ul>  
<div class="tab-contents">
<div class="tab-content-active">
Tab Content 1
</div>  
<div>
Tab Content 2
</div>  
<div>
Tab Content 3
</div>
</div> 
</div>  

</div>

我正在尝试在 Vanilla JavaScript 的第 6 行生成这些唯一的 ID(accessibleTabsContainers.forEach),但它不起作用。

任何协助将不胜感激。

我解决了自己的问题。在onTabSelectorClick函数内部迭代的forEach循环中,我重构了代码以添加以下行:

var tabSelectorSelected = e.target;
var accessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container'); 
var tabSelectorsSelectedFromTabs = accessibleTabsContainerSelected.querySelectorAll('ul > li');

然后在forEach循环中,我使用了tabSelectorsSelectedFromTabs,它引用div了标签(var accessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container');)中的选项卡元素,而不是遍历tabSelector(引用var tabSelector = document.querySelectorAll('.tab-selectors > li');)并遍历所有选项卡li标签,而不仅仅是单击的元素引用的选项卡var tabSelectorSelected = e.target;li元素

()。请参阅 https://codepen.io/hollyw00d/pen/JjYJWjG。另外,我在此答案中添加了正确的代码。下面是代码前后更有用的描述:

在 Click 事件处理程序中传递onTabSelectorClick函数内的forEach循环代码段不正确

var tabSelector = document.querySelectorAll('.tab-selectors > li');
function onTabSelectorClick(e) {
tabSelector.forEach(function() {
// Code here
});
}

更正在 Click 事件处理程序中传递onTabSelectorClick函数内的forEach循环代码段

var tabSelectorSelected = e.target;
var accessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container'); 
var tabSelectorsSelectedFromTabs = accessibleTabsContainerSelected.querySelectorAll('ul > li');
function onTabSelectorClick(e) {
tabSelectorsSelectedFromTabs.forEach(function() {
// Code here
});
}

var accessibleTabsContainers = document.querySelectorAll('.accessible-tabs-container');
var tabSelector = document.querySelectorAll('.tab-selectors > li');
var tabContent = document.querySelectorAll('.tab-contents > div');
var largeRandNumber = Math.floor((Math.random() * 1000) + 1000);
accessibleTabsContainers.forEach(function(elem, indexAccessibleTabContainer) {
elem.setAttribute('data-id', indexAccessibleTabContainer);

tabSelector.forEach(function(singleTabSelector, i) {

var tabSelectorId = 'tab-selector-' + largeRandNumber + '_' + i + '_' + indexAccessibleTabContainer;
var ariaControlTabContent = 'tab-content-' + largeRandNumber + '_' + i + '_' + indexAccessibleTabContainer;
singleTabSelector.setAttribute('data-id', i);
singleTabSelector.setAttribute('id', tabSelectorId);
singleTabSelector.setAttribute('aria-controls', ariaControlTabContent);
tabContent[i].setAttribute('data-id', i);
tabContent[i].setAttribute('tabindex', 0);
tabContent[i].setAttribute('role', 'tabpanel');
tabContent[i].setAttribute('id', ariaControlTabContent);
tabContent[i].setAttribute('aria-labeledby', tabSelectorId);
if(i === 0) {
singleTabSelector.setAttribute('aria-pressed', 'true');
} else {
singleTabSelector.setAttribute('aria-pressed', 'false');
singleTabSelector.setAttribute('tabindex', -1);
}
});
});  
function onTabSelectorClick(e) {
var tabSelectorSelected = e.target;
var accessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container'); 
var tabSelectorsSelectedFromTabs = accessibleTabsContainerSelected.querySelectorAll('ul > li');
var tabContentsSelectedFromContainer = accessibleTabsContainerSelected.querySelectorAll('.tab-contents > div');

if(!tabSelectorSelected.classList.contains('active-tab-selector')) {
tabSelectorsSelectedFromTabs.forEach(function(singleTabSelected, i) {
if(tabSelectorSelected.getAttribute('data-id') === tabContentsSelectedFromContainer[i].getAttribute('data-id')) {
singleTabSelected.classList.add('active-tab-selector');
singleTabSelected.setAttribute('tabindex', 0);
singleTabSelected.setAttribute('aria-pressed', 'true');
tabContentsSelectedFromContainer[i].classList.add('tab-content-active');
} else {
singleTabSelected.classList.remove('active-tab-selector');
singleTabSelected.setAttribute('tabindex', -1);
singleTabSelected.setAttribute('aria-pressed', 'false');
tabContentsSelectedFromContainer[i].classList.remove('tab-content-active');
}
});
}

}
tabSelector.forEach(function(tabSelector) {
tabSelector.addEventListener('click', onTabSelectorClick);
});
.wrapper {
max-width: 960px;
margin: 0 auto;
}
.tab-selectors {
display: inline-block;
}
.tab-selectors > li {
padding: 10px;
}
.tab-selectors > .active-tab-selector {
border: 1px solid #f00; 
}
.tab-content {
display: inline-block;
}
.tab-contents > div {
padding: 10px;
border: 2px solid #000;
height: 150px;
width: 150px;
display: none;
}
.tab-contents > .tab-content-active {
display: block;
}
<div class="wrapper">
<h1>Accessible Tabs using Vanilla JavaScript</h1>

<div class="accessible-tabs-container">  


<ul role="tablist" aria-lable="Tabs Example" class="tab-selectors">
<li class="active-tab-selector">Tab Selector 1</li>
<li>Tab Selector 2</li>
<li>Tab Selector 3</li>
</ul>  

<div class="tab-contents">
<div class="tab-content-active">
Tab Content 1
</div>  
<div>
Tab Content 2
</div>  
<div>
Tab Content 3
</div>
</div> 
</div>

<div class="accessible-tabs-container">  


<ul role="tablist" aria-lable="Tabs Example" class="tab-selectors">
<li class="active-tab-selector">Tab Selector 1</li>
<li>Tab Selector 2</li>
<li>Tab Selector 3</li>
</ul>  

<div class="tab-contents">
<div class="tab-content-active">
Tab Content 1
</div>  
<div>
Tab Content 2
</div>  
<div>
Tab Content 3
</div>
</div> 
</div>  

</div>

最新更新