Добавление нескольких вкладок Vanilla JavaScript на одну страницу - PullRequest
1 голос
/ 05 мая 2020

Используя вариант следующего кода, я смог успешно добавить один набор вкладок Vanilla JavaScript.

Тем не менее, как мне добавить несколько наборов JavaScript вкладок на одну страницу, используя те же классы в HTML.

Мне сложно создать уникальные динамические c идентификаторы для селекторов вкладок и областей содержимого вкладок, используя JavaScript. Как видно из https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-1/tabs.html, эти уникальные идентификаторы необходимы для доступных тегов.

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>  

Я пытаюсь сгенерировать эти уникальные идентификаторы в строке 6 Vanilla JavaScript (accessibleTabsContainers.forEach), но это не работает.

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 12 мая 2020

Я решил свою проблему. В forEach l oop, который выполняет итерацию внутри функции onTabSelectorClick, я реорганизовал код, добавив следующие строки:

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

Затем в forEach l oop вместо повторения через tabSelector (который ссылается на var tabSelector = document.querySelectorAll('.tab-selectors > li');) и перебирает все теги вкладок li, а не только те, на которые ссылается выбранный элемент, я использовал tabSelectorsSelectedFromTabs, который ссылается на элементы вкладки внутри их родительского тега div ( var accessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container');), из элемента вкладки (тег li) щелкнул (var tabSelectorSelected = e.target;).

См. https://codepen.io/hollyw00d/pen/JjYJWjG. Кроме того, я добавил правильный код в этот ответ. Ниже приведено более полезное описание кода до и после:

Неправильно forEach L oop Фрагмент внутри функции onTabSelectorClick, которая передается в обработчике событий щелчка

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

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

Правильно forEach L oop Фрагмент внутри onTabSelectorClick функции, переданной в обработчике событий щелчка

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>  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...