Adloun

JavaScript : rendre le Web interactif (école d'ingénieur) · Chapitre 8 · Exercice de TD

Des onglets au clavier

Événements et formulaires · niveau 3 (difficile)

Énoncé

La fiche d'un livre présente trois onglets (Résumé, Sommaire, Avis), balisés avec les rôles ARIA tablist, tab et tabpanel. Écrire le script : un clic sur un onglet l'active (aria-selected, panneau affiché, les autres cachés) ; seul l'onglet actif est dans l'ordre de tabulation (tabIndex 0, les autres ) ; les flèches gauche et droite passent à l'onglet voisin (en boucle), Début et Fin au premier et au dernier.


<div role="tablist" aria-label="Fiche du livre">
  <button type="button" role="tab" id="t1" aria-controls="p1" aria-selected="true">Résumé</button>
  <button type="button" role="tab" id="t2" aria-controls="p2" aria-selected="false" tabindex="-1">Sommaire</button>
  <button type="button" role="tab" id="t3" aria-controls="p3" aria-selected="false" tabindex="-1">Avis</button>
</div>
<section role="tabpanel" id="p1" aria-labelledby="t1" tabindex="0"><p>Un cours complet…</p></section>
<section role="tabpanel" id="p2" aria-labelledby="t2" tabindex="0" hidden><p>16 chapitres…</p></section>
<section role="tabpanel" id="p3" aria-labelledby="t3" tabindex="0" hidden><p>« Très clair. »</p></section>

Corrigé


const onglets = [...document.querySelectorAll("[role=tab]")];

function activer(onglet) {
  for (const o of onglets) {
    const actif = o === onglet;
    o.setAttribute("aria-selected", String(actif));
    o.tabIndex = actif ? 0 : -1;
    document.getElementById(o.getAttribute("aria-controls")).hidden = !actif;
  }
  onglet.focus();
  console.log("onglet :", onglet.textContent);
}

const liste = document.querySelector("[role=tablist]");
liste.addEventListener("click", (e) => {
  const onglet = e.target.closest("[role=tab]");
  if (onglet) {
    activer(onglet);
  }
});

// Flèches gauche et droite (en boucle), Début et Fin.
liste.addEventListener("keydown", (e) => {
  const i = onglets.indexOf(document.activeElement);
  const n = onglets.length;
  const cibles = { ArrowRight: (i + 1) % n, ArrowLeft: (i - 1 + n) % n, Home: 0, End: n - 1 };
  if (e.key in cibles) {
    e.preventDefault();
    activer(onglets[cibles[e.key]]);
  }
});

On appuie sur Tab (le focus arrive sur l'onglet actif), puis sur flèche gauche, flèche droite et Fin, on clique sur « Sommaire », et l'on appuie sur Tab :


onglet : Avis
onglet : Résumé
onglet : Avis
onglet : Sommaire
focus après Tab : SECTION#p2
panneaux visibles : p2

La flèche gauche depuis le premier onglet boucle sur le dernier. Comme les onglets inactifs ont tabIndex = -1, la touche Tab quitte la liste d'onglets et va directement au panneau affiché (qui porte tabindex="0") : c'est le comportement recommandé pour des onglets accessibles, où les flèches servent à choisir et Tab à avancer.

100 % gratuit

La suite du chapitre est sur Adloun

Exercice suivant et tuteur

Sans compte : le cours et le premier QCM. Exercices et tuteur : inscription gratuite en 30 secondes, sans carte bancaire.

Le cours du chapitre · Tous les exercices du chapitre

Exercice suivant et tuteur →