Frage zum Wiki-Artikel „zugängliche Registerkarten“
mAndreas
- frage zum wiki
- javascript
Hallo, ich möchte dieses TabPanel gerne 2 mal auf einer Seite einbauen. Was muss geändert werden, damit das TabPanel 2 unabhängig vom TabPanel1 funktioniert?
hallo
Hallo, ich möchte dieses TabPanel gerne 2 mal auf einer Seite einbauen. Was muss geändert werden, damit das TabPanel 2 unabhängig vom TabPanel1 funktioniert?
Zuerst mal sollte man dieses zugängliche Beispiel fertig machen.
Da findet sich nämlich so code:
<ul role="tablist" id="tablist">
<li id="link1" role="tab" aria-controls="panel-1" aria-selected="true" tabindex="0">1 - Button</li>
<li id="link2" role="tab" aria-controls="panel-2" aria-selected="false" tabindex="0">2 - Button</li>
<li id="link3" role="tab" aria-controls="panel-3" aria-selected="false" tabindex="0">3 - Button</li>
</ul>
tabindex="0" schaltet nämlich den Focus für solche Elemente ab.
Man hätte hier besser effektiv <button>-Elemente verwenden sollen.
Was du aber ändern müsstst um mehrere Tab-Bereiche zu vwerwenden wird hier klar:
function init() {
var tab = document.getElementById('tabpanel');
tab.addEventListener('click',clickHandler);
tab.addEventListener('keypress', keyHandler);
}
statt id=tabpanel einfach class= "tabpanel" verwenden.
dann oben ändern zu
function init() {
document.queryselectorAll('.tabpanel')
.forEach(function(item){
item.addEventListener('click',clickHandler);
item.addEventListener('keypress', keyHandler);
});
}
Hallo
Auch sollte aus #tablist
für die <ul>
eine Klasse werden, also z.B. <ul class="tablist">
und im CSS .tablist
. Im CSS müssen, als Folge daraus, noch an diversen Stellen die Selektoren angepasst werden.
Die IDs der einzelnen Tabs müssen dort und in den auslösenden Buttons auch noch geändert werden. Im zweiten tab-Panel müssen sie sich ja von denen im ersten Panel unterscheiden, da die IDs dokumentweit eindeutig sein müssen. Eine Durchnummerierung der IDs im <div>
und die dazu passende Anpassung von aria-controls
in den <li>
sollte an der Stelle reichen.
<!-- in der Tabliste (#tablist oder .tablist) -->
<li id="link1" role="tab" aria-controls="panel-1">1 - Button</li>
<!-- im inhaltsblock (#tabcontent oder .tabcontent) -->
<div id="panel-1" role="tabpanel" aria-labelledby="link1">
Am JS-Code scheinen, über die von dir genannten, keine weiteren Änderungen nötig zu sein. Das Element, dass konkret benutzt wurde wird ja als Target ermittelt.
Man hätte hier [in der Tabliste] besser effektiv <button>-Elemente verwenden sollen.
Dann funktioniert das Beispiel ohne JS nicht mehr, oder? Wäre es da nicht sinnvoll, die Gestaltung als Tabbeable Interface per JS überhaupt erst einzuschalten und ohne JS normal untereinander liegende Blockelemente anzuzeigen?
Allerdings hört es dann auch auf, einfach zu sein.
Tschö, Auge
hallo
Man hätte hier [in der Tabliste] besser effektiv <button>-Elemente verwenden sollen.
Dann funktioniert das Beispiel ohne JS nicht mehr, oder? Wäre es da nicht sinnvoll, die Gestaltung als Tabbeable Interface per JS überhaupt erst einzuschalten und ohne JS normal untereinander liegende Blockelemente anzuzeigen?
Allerdings hört es dann auch auf, einfach zu sein.
Da ich gerade den Editor offen habe für eine details/summary Version (ohne diese Elemente zu verwenden)
.details {list-style:none; width:20rem; }
.details li {list-style:none; padding: 0 1rem; box-shadow:0px 0px 4px 0px #666; margin: 1rem 0; }
.details button {padding:0 1rem 0 0.5rem; display:block; }
.details button[aria-expanded="true"] + .content {display:block}
.details button[aria-expanded="false"] + .content {display:none}
.details button[aria-expanded="true"]:before {content:"▼ "; }
.details button[aria-expanded="false"]:before {content:"▶ "; }
<ul class="details">
<li><button aria-expanded="false">Show</button><div class="content"><p>lorem ipsm dolres sunt</p></div></li>
<li><button aria-expanded="false">Show</button><div class="content"><p>lorem ipsm dolres sunt</p></div></li>
<li><button aria-expanded="false">Show</button><div class="content"><p>Mit mehr Details...</p>
<ul>
<li><button aria-expanded="false">Show</button><div class="content"><p>lorem ipsm dolres sunt</p></div></li>
<li><button aria-expanded="false">Show</button><div class="content"><p>lorem ipsm dolres sunt</p></div></li>
<li><button aria-expanded="false">Show</button><div class="content"><p>lorem ipsm dolres sunt</p>
</div></li>
</ul>
</div></li>
</ul>
document.querySelectorAll(".details").forEach( function(item){
item.addEventListener(
"click",
function(ev){
if( ev.target.getAttribute("aria-expanded") == "false" ){
//soll nur eines der Sybling Elemente offen sein?
//sonst ausklammern
ev.target.parentElement.parentElementquerySelectorAll("button")
.forEach(function(item){item.setAttribute("aria-expanded",false)});
//
ev.target.setAttribute("aria-expanded",true);
}
else{
ev.target.setAttribute("aria-expanded",false);
}
}
);
});
Das Verhalten im JS lässt sich ändern. Man kann dieses Beispiel im CSS zu tabpaneln umgestalten.
Hallo beatovich,
tabindex="0" schaltet nämlich den Focus für solche Elemente ab.
ganz sicher?
Grüße, Martl
hallo
Hallo beatovich,
tabindex="0" schaltet nämlich den Focus für solche Elemente ab.
ganz sicher?
Grandioser bullshit meinerseits…
Jetzt habe ich nach einem Schuldigen gesucht, warum Tab-Taste nicht die entsprechenden Elemente fokusiert...
@@beatovich
tabindex="0" schaltet nämlich den Focus für solche Elemente ab.
Das ist ja schon geklärt.
Man hätte hier besser effektiv <button>-Elemente verwenden sollen.
Links. Wie in Inclusive Components: Tabbed Interfaces
LLAP 🖖
Mir ist es schon fast unangenehm aber nachfolgend der geänderte Stand, der leider nicht funktioniert:
<script>
'use strict';
function init() {
document.queryselectorAll('.tabpanel')
.forEach(function(item){
item.addEventListener('click',clickHandler);
item.addEventListener('keypress', keyHandler);
});
}
function clickHandler(elem) {
var target = elem.target;
var selectedTab = document.querySelector('[aria-selected="true"]');
selectedTab.setAttribute('aria-selected', false);
target.setAttribute('aria-selected', true);
var panels = document.querySelector('[aria-hidden="false"]');
panels.setAttribute('aria-hidden', true);
var panelId = target.getAttribute('aria-controls'),
panel = document.getElementById(panelId);
panel.setAttribute('aria-hidden', false);
}
document.addEventListener("DOMContentLoaded", function () {
init();
});
}());
</script>
<div class="tabpanel">
<ul role="tablist" id="tablist">
<h2>
<li id="link1" role="tab" aria-controls="panel-1" aria-selected="true">Button1</li>
<li id="link2" role="tab" aria-controls="panel-2" aria-selected="false">Button2</li>
</h2>
</ul>
<div id="tabcontent">
<div id="panel-1" role="tabpanel" aria-labelledby="link1" aria-hidden="false">
Text1
</div>
</div>
<div id="tabcontent">
<div id="panel-2" role="tabpanel" aria-labelledby="link2" aria-hidden="true">
Text2
</div>
</div>
</div>
Darauf folgen andere Inhalte… bevor es mit dem gewünschten zweiten TabPanel weiter geht
<div class="tabpanel">
<ul role="tablist" id="tablist">
<h2>
<li id="link3" role="tab" aria-controls="panel-3" aria-selected="true">Button3</li>
<li id="link4" role="tab" aria-controls="panel-4" aria-selected="false">Button4</li>
<li id="link5" role="tab" aria-controls="panel-5" aria-selected="false">Button5</li>
</h2>
</ul>
<div id="tabcontent">
<div id="panel-3" role="tabpanel" aria-labelledby="link3" aria-hidden="false">
Text3
</div>
</div>
<div id="tabcontent">
<div id="panel-4" role="tabpanel" aria-labelledby="link4" aria-hidden="true">
Text4
</div>
</div>
<div id="tabcontent">
<div id="panel-5" role="tabpanel" aria-labelledby="link5" aria-hidden="true">
Text5
</div>
</div>
</div>
hallo
Mir ist es schon fast unangenehm aber nachfolgend der geänderte Stand, der leider nicht funktioniert:
<script> 'use strict'; function init() { document.queryselectorAll('.tabpanel') .forEach(function(item){ item.addEventListener('click',clickHandler); item.addEventListener('keypress', keyHandler); }); } function clickHandler(elem) { var target = elem.target; var selectedTab = document.querySelector('[aria-selected="true"]');
Da du mehrere tab-panels verwendest willst du nur das Element ändern, IN WELCHEM der Event stattfindet. Deshalb:
var selectedTab = elem.querySelector('[aria-selected="true"]');
selectedTab.setAttribute('aria-selected', false); target.setAttribute('aria-selected', true); var panels = document.querySelector('[aria-hidden="false"]');
auch hier:
var panels = elem.querySelector('[aria-hidden="false"]');
panels.setAttribute('aria-hidden', true); var panelId = target.getAttribute('aria-controls'), panel = document.getElementById(panelId); panel.setAttribute('aria-hidden', false);
} document.addEventListener("DOMContentLoaded", function () { init(); }); }());
</script>
hallo
<div id="tabcontent">
ids müssen einmalig sein pro document. Ergo musst du hier class="tabcontent" verwenden
Vielen Dank für die schnelle Hilfe. Leider ist aber die Funktion damit nicht mehr gegeben. Bei beiden Menüs passiert nichts mehr beim klicken der Tabs.