在同一页面上创建多个选项卡面板时出现问题。下面是参考脚本与一个选项卡面板的配合使用。如果我再添加一个选项卡面板,则该脚本将无法正常运行,因为它是基于角色属性运行的。
请让我知道如何使用相同的脚本创建唯一的标签面板。
LINK:https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-2/tabs.html
/*
* This content is licensed according to the W3C Software License at
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
*/
(function () {
var tablist = document.querySelectorAll('[role="tablist"]')[0];
var tabs;
var panels;
generateArrays();
function generateArrays () {
tabs = document.querySelectorAll('[role="tab"]');
panels = document.querySelectorAll('[role="tabpanel"]');
};
// For easy reference
var keys = {
end: 35,
home: 36,
left: 37,
up: 38,
right: 39,
down: 40,
delete: 46,
enter: 13,
space: 32
};
// Add or substract depenign on key pressed
var direction = {
37: -1,
38: -1,
39: 1,
40: 1
};
// Bind listeners
for (i = 0; i < tabs.length; ++i) {
addListeners(i);
};
function addListeners (index) {
tabs[index].addEventListener('click', clickEventListener);
tabs[index].addEventListener('keydown', keydownEventListener);
tabs[index].addEventListener('keyup', keyupEventListener);
// Build an array with all tabs (<button>s) in it
tabs[index].index = index;
};
// When a tab is clicked, activateTab is fired to activate it
function clickEventListener (event) {
var tab = event.target;
activateTab(tab, false);
};
// Handle keydown on tabs
function keydownEventListener (event) {
var key = event.keyCode;
switch (key) {
case keys.end:
event.preventDefault();
// Activate last tab
focusLastTab();
break;
case keys.home:
event.preventDefault();
// Activate first tab
focusFirstTab();
break;
// Up and down are in keydown
// because we need to prevent page scroll >:)
case keys.up:
case keys.down:
determineOrientation(event);
break;
};
};
// Handle keyup on tabs
function keyupEventListener (event) {
var key = event.keyCode;
switch (key) {
case keys.left:
case keys.right:
determineOrientation(event);
break;
case keys.delete:
determineDeletable(event);
break;
case keys.enter:
case keys.space:
activateTab(event.target);
break;
};
};
// When a tablist’s aria-orientation is set to vertical,
// only up and down arrow should function.
// In all other cases only left and right arrow function.
function determineOrientation (event) {
var key = event.keyCode;
var vertical = tablist.getAttribute('aria-orientation') == 'vertical';
var proceed = false;
if (vertical) {
if (key === keys.up || key === keys.down) {
event.preventDefault();
proceed = true;
};
}
else {
if (key === keys.left || key === keys.right) {
proceed = true;
};
};
if (proceed) {
switchTabOnArrowPress(event);
};
};
// Either focus the next, previous, first, or last tab
// depening on key pressed
function switchTabOnArrowPress (event) {
var pressed = event.keyCode;
if (direction[pressed]) {
var target = event.target;
if (target.index !== undefined) {
if (tabs[target.index + direction[pressed]]) {
tabs[target.index + direction[pressed]].focus();
}
else if (pressed === keys.left || pressed === keys.up) {
focusLastTab();
}
else if (pressed === keys.right || pressed == keys.down) {
focusFirstTab();
};
};
};
};
// Activates any given tab panel
function activateTab (tab, setFocus) {
setFocus = setFocus || true;
// Deactivate all other tabs
deactivateTabs();
// Remove tabindex attribute
tab.removeAttribute('tabindex');
// Set the tab as selected
tab.setAttribute('aria-selected', 'true');
// Get the value of aria-controls (which is an ID)
var controls = tab.getAttribute('aria-controls');
// Remove hidden attribute from tab panel to make it visible
document.getElementById(controls).removeAttribute('hidden');
// Set focus when required
if (setFocus) {
tab.focus();
};
};
// Deactivate all tabs and tab panels
function deactivateTabs () {
for (t = 0; t < tabs.length; t++) {
tabs[t].setAttribute('tabindex', '-1');
tabs[t].setAttribute('aria-selected', 'false');
};
for (p = 0; p < panels.length; p++) {
panels[p].setAttribute('hidden', 'hidden');
};
};
// Make a guess
function focusFirstTab () {
tabs[0].focus();
};
// Make a guess
function focusLastTab () {
tabs[tabs.length - 1].focus();
};
// Detect if a tab is deletable
function determineDeletable (event) {
target = event.target;
if (target.getAttribute('data-deletable') !== null) {
// Delete target tab
deleteTab(event, target);
// Update arrays related to tabs widget
generateArrays();
// Activate the closest tab to the one that was just deleted
if (target.index - 1 < 0) {
activateTab(tabs[0]);
}
else {
activateTab(tabs[target.index - 1]);
};
};
};
// Deletes a tab and its panel
function deleteTab (event) {
var target = event.target;
var panel = document.getElementById(target.getAttribute('aria-controls'));
target.parentElement.removeChild(target);
panel.parentElement.removeChild(panel);
};
// Determine whether there should be a delay
// when user navigates with the arrow keys
function determineDelay () {
var hasDelay = tablist.hasAttribute('data-delay');
var delay = 0;
if (hasDelay) {
var delayValue = tablist.getAttribute('data-delay');
if (delayValue) {
delay = delayValue;
}
else {
// If no value is specified, default to 300ms
delay = 300;
};
};
return delay;
};
}());
.tabs {
width: 20em;
font-family: "lucida grande", sans-serif;
}
[role="tablist"] {
margin: 0 0 -0.1em;
overflow: visible;
}
[role="tab"] {
position: relative;
margin: 0;
padding: 0.3em 0.5em 0.4em;
border: 1px solid hsl(219, 1%, 72%);
border-radius: 0.2em 0.2em 0 0;
box-shadow: 0 0 0.2em hsl(219, 1%, 72%);
overflow: visible;
font-family: inherit;
font-size: inherit;
background: hsl(220, 20%, 94%);
}
[role="tab"]:hover::before,
[role="tab"]:focus::before,
[role="tab"][aria-selected="true"]::before {
position: absolute;
bottom: 100%;
right: -1px;
left: -1px;
border-radius: 0.2em 0.2em 0 0;
border-top: 3px solid hsl(20, 96%, 48%);
content: '';
}
[role="tab"][aria-selected="true"] {
border-radius: 0;
background: hsl(220, 43%, 99%);
outline: 0;
}
[role="tab"][aria-selected="true"]:not(:focus):not(:hover)::before {
border-top: 5px solid hsl(218, 96%, 48%);
}
[role="tab"][aria-selected="true"]::after {
position: absolute;
z-index: 3;
bottom: -1px;
right: 0;
left: 0;
height: 0.3em;
background: hsl(220, 43%, 99%);
box-shadow: none;
content: '';
}
[role="tab"]:hover,
[role="tab"]:focus,
[role="tab"]:active {
outline: 0;
border-radius: 0;
color: inherit;
}
[role="tab"]:hover::before,
[role="tab"]:focus::before {
border-color: hsl(20, 96%, 48%);
}
[role="tabpanel"] {
position: relative;
z-index: 2;
padding: 0.5em 0.5em 0.7em;
border: 1px solid hsl(219, 1%, 72%);
border-radius: 0 0.2em 0.2em 0.2em;
box-shadow: 0 0 0.2em hsl(219, 1%, 72%);
background: hsl(220, 43%, 99%);
}
[role="tabpanel"]:focus {
border-color: hsl(20, 96%, 48%);
box-shadow: 0 0 0.2em hsl(20, 96%, 48%);
outline: 0;
}
[role="tabpanel"]:focus::after {
position: absolute;
bottom: 0;
right: -1px;
left: -1px;
border-bottom: 3px solid hsl(20, 96%, 48%);
border-radius: 0 0 0.2em 0.2em;
content: '';
}
[role="tabpanel"] p {
margin: 0;
}
[role="tabpanel"] * + p {
margin-top: 1em;
}
<div class="tabs">
<div role="tablist" aria-label="Entertainment">
<button role="tab"
aria-selected="true"
aria-controls="nils-tab"
id="nils">
Nils Frahm
</button>
<button role="tab"
aria-selected="false"
aria-controls="agnes-tab"
id="agnes"
tabindex="-1">
Agnes Obel
</button>
<button role="tab"
aria-selected="false"
aria-controls="complexcomplex"
id="complex"
tabindex="-1"
data-deletable="">
Joke
</button>
</div>
<div tabindex="0"
role="tabpanel"
id="nils-tab"
aria-labelledby="nils">
<p>
Nils Frahm is a German musician, composer and record producer based in Berlin. He is known for combining classical and electronic music and for an unconventional approach to the piano in which he mixes a grand piano, upright piano, Roland Juno-60, Rhodes piano, drum machine, and Moog Taurus.
</p>
</div>
<div tabindex="0"
role="tabpanel"
id="agnes-tab"
aria-labelledby="agnes"
hidden="">
<p>
Agnes Caroline Thaarup Obel is a Danish singer/songwriter. Her first album, Philharmonics, was released by PIAS Recordings on 4 October 2010 in Europe. Philharmonics was certified gold in June 2011 by the Belgian Entertainment Association (BEA) for sales of 10,000 Copies.
</p>
</div>
<div tabindex="0"
role="tabpanel"
id="complexcomplex"
aria-labelledby="complex"
hidden="">
<p>
Fear of complicated buildings:
</p>
<p>
A complex complex complex.
</p>
</div>
</div>
<div class="tabs" id="tabpanel2">
<div role="tablist" aria-label="Entertainment">
<button role="tab"
aria-selected="true"
aria-controls="nils-tab1"
id="nils1">
Nils Frahm
</button>
<button role="tab"
aria-selected="false"
aria-controls="agnes-tab1"
id="agnes"
tabindex="-1">
Agnes Obel
</button>
<button role="tab"
aria-selected="false"
aria-controls="complexcomplex1"
id="complex1"
tabindex="-1"
data-deletable="">
Joke
</button>
</div>
<div tabindex="0"
role="tabpanel"
id="nils-tab1"
aria-labelledby="nils1">
<p>
Nils Frahm is a German musician, composer and record producer based in Berlin. He is known for combining classical and electronic music and for an unconventional approach to the piano in which he mixes a grand piano, upright piano, Roland Juno-60, Rhodes piano, drum machine, and Moog Taurus.
</p>
</div>
<div tabindex="0"
role="tabpanel"
id="agnes-tab1"
aria-labelledby="agnes1"
hidden="">
<p>
Agnes Caroline Thaarup Obel is a Danish singer/songwriter. Her first album, Philharmonics, was released by PIAS Recordings on 4 October 2010 in Europe. Philharmonics was certified gold in June 2011 by the Belgian Entertainment Association (BEA) for sales of 10,000 Copies.
</p>
</div>
<div tabindex="0"
role="tabpanel"
id="complexcomplex1"
aria-labelledby="complex1"
hidden="">
<p>
Fear of complicated buildings:
</p>
<p>
A complex complex complex.
</p>
</div>
</div>
问题:我在页面上有2个单独的标签面板,我试图使用向左和向右箭头或单击每个标签来访问,但是相应的标签内容无法正确隐藏。