将多个 Vanilla JavaScript 选项卡添加到同一页面 [英] Adding Multiple Vanilla JavaScript Tabs to the Same Page

查看:18
本文介绍了将多个 Vanilla JavaScript 选项卡添加到同一页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

但是如何使用 HTML 中的相同类将多组 JavaScript 选项卡添加到一个页面.

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

varaccessableTabsContainers = 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);accessTabsContainers.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);如果(我 === 0){tabSelector[i].setAttribute('aria-pressed', 'true');} 别的 {tabSelector[i].setAttribute('aria-pressed', 'false');tabSelector[i].setAttribute('tabindex', -1);}});});函数 onTabSelectorClick(e) {accessTabsContainers.forEach(function(accessibleTabsContainer, indexAccessibleTabContainer) {var tabSelectorSelected = e.target;varaccessableTabsContainerSelected = tabSelectorSelected.parentElement.parentElement;if(!tabSelectorSelected.classList.contains('active-tab-selector')) {var tabSelectorSelectedFromContainer = accessibilityTabsContainerSelected.querySelectorAll('.tab-contents > div');控制台日志(tabSelectorSelectedFromContainer);tabSelector.forEach(function(singleTabSelected, i) {if(tabSelectorSelected.getAttribute('data-id') === tabContent[i].getAttribute('data-id')) {tabContent[i].classList.add('tab-content-active');} 别的 {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 {最大宽度:960px;边距:0 自动;}.tab 选择器 {显示:内联块;}.tab-selectors >李{填充:10px;}.tab-selectors >.active-tab-selector {边框:1px 实心 #f00;}.tab 内容{显示:内联块;}.tab-contents >div {填充:10px;边框:2px 实心 #000;高度:150px;宽度:150px;显示:无;}.tab-contents >.tab-content-active {显示:块;}

<h1>使用 Vanilla JavaScript 的可访问标签</h1><div class="accessible-tabs-container"><ul role="tablist" aria-lable="Tabs Example" class="tab-selectors"><li class="active-tab-selector">选项卡选择器 1</li><li>选项卡选择器 2</li><li>选项卡选择器 3</li><div class="tab-contents"><div class="tab-content-active">标签内容 1

<div>标签内容 2

<div>标签内容 3

<div class="accessible-tabs-container"><ul role="tablist" aria-lable="Tabs Example" class="tab-selectors"><li class="active-tab-selector">选项卡选择器 1</li><li>选项卡选择器 2</li><li>选项卡选择器 3</li><div class="tab-contents"><div class="tab-content-active">标签内容 1

<div>标签内容 2

<div>标签内容 3

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

如有任何帮助,我们将不胜感激.

解决方案

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

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

然后在 forEach 循环中而不是通过 tabSelector 迭代(它引用 var tabSelector = document.querySelectorAll('.tab-selectors > li');) 并遍历所有标签 li 标签,而不仅仅是被点击的元素引用的标签,我使用了 tabSelectorsSelectedFromTabs,它引用了它们父元素中的标签元素div 标签(varaccessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container');),来自 tab 元素(li 标签) 点击 (var tabSelectorSelected = e.target;).

请参阅 https://codepen.io/hollyw00d/pen/JjYJWjG.另外,我在这个答案中添加了正确的代码.下面是一段更有用的前后代码说明:

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

var tabSelector = document.querySelectorAll('.tab-selectors > li');函数 onTabSelectorClick(e) {tabSelector.forEach(function() {//代码在这里});}

正确的 forEach 循环片段在 onTabSelectorClick 函数中,传入 Click 事件处理程序

var tabSelectorSelected = e.target;varaccessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container');var tabSelectorsSelectedFromTabs = accessibilityTabsContainerSelected.querySelectorAll('ul > li');函数 onTabSelectorClick(e) {tabSelectorsSelectedFromTabs.forEach(function() {//代码在这里});}

varaccessableTabsContainers = 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);accessTabsContainers.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);如果(我 === 0){singleTabSelector.setAttribute('aria-pressed', 'true');} 别的 {singleTabSelector.setAttribute('aria-pressed', 'false');singleTabSelector.setAttribute('tabindex', -1);}});});函数 onTabSelectorClick(e) {var tabSelectorSelected = e.target;varaccessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container');var tabSelectorsSelectedFromTabs = accessibilityTabsContainerSelected.querySelectorAll('ul > li');var tabContentsSelectedFromContainer = accessibilityTabsContainerSelected.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');} 别的 {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 {最大宽度:960px;边距:0 自动;}.tab 选择器 {显示:内联块;}.tab-selectors >李{填充:10px;}.tab-selectors >.active-tab-selector {边框:1px 实心 #f00;}.tab 内容{显示:内联块;}.tab-contents >div {填充:10px;边框:2px 实心 #000;高度:150px;宽度:150px;显示:无;}.tab-contents >.tab-content-active {显示:块;}

<h1>使用 Vanilla JavaScript 的可访问标签</h1><div class="accessible-tabs-container"><ul role="tablist" aria-lable="Tabs Example" class="tab-selectors"><li class="active-tab-selector">选项卡选择器 1</li><li>选项卡选择器 2</li><li>选项卡选择器 3</li><div class="tab-contents"><div class="tab-content-active">标签内容 1

<div>标签内容 2

<div>标签内容 3

<div class="accessible-tabs-container"><ul role="tablist" aria-lable="Tabs Example" class="tab-selectors"><li class="active-tab-selector">选项卡选择器 1</li><li>选项卡选择器 2</li><li>选项卡选择器 3</li><div class="tab-contents"><div class="tab-content-active">标签内容 1

<div>标签内容 2

<div>标签内容 3

Using a variation of the following code, I was able to successfully add one set of Vanilla JavaScript tabs.

Yet how to do I add multiple sets of JavaScript tabs to one page using the same classes in the HTML.

I'm having difficultly creating unique dynamic IDs for the tab selectors and tab content areas using JavaScript. As you can see in https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-1/tabs.html, these unique IDs are needed for accessible tags.

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>  

I'm trying to generate these unique IDs in line 6 of the Vanilla JavaScript (accessibleTabsContainers.forEach) but it's not working.

Any assistance would be appreciated.

解决方案

I solved my own issue. In the forEach loop that iterates inside the onTabSelectorClick function, I refactored the code to add the lines below:

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

Then in a forEach loop instead of iterating through tabSelector (which references var tabSelector = document.querySelectorAll('.tab-selectors > li');) and loops through all tabs li tags, not just the ones referenced by the element clicked, I used tabSelectorsSelectedFromTabs, which references the tab elements inside their parent div tag (var accessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container');), from the tab element (li tag) clicked (var tabSelectorSelected = e.target;).

See https://codepen.io/hollyw00d/pen/JjYJWjG. Also, I added the correct code in this answer. Below is a more useful before and after description of the code:

Incorrect forEach Loop Snippet inside onTabSelectorClick function that is passed in Click Event Handler

var tabSelector = document.querySelectorAll('.tab-selectors > li');

function onTabSelectorClick(e) {
   tabSelector.forEach(function() {
     // Code here
   });
}

Correct forEach Loop Snippet inside onTabSelectorClick function that is passed in Click Event Handler

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>  

这篇关于将多个 Vanilla JavaScript 选项卡添加到同一页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆