La communauté ALL HTML c'est 58880 membres à ce jour dont 6 inscrits aujourd'hui et 38 depuis une semaine.

Communauté ALL HTML : koala64

Menu déroulant accessible

Cet article est actuellement publié sur le site.

Photo de koala64 Article publié le lundi 10 juillet 2006 par koala64.
Cet article est classé dans les catégories « Javascript »

Menu déroulant fondé sur les langages xhtml, css et javascript permettant la navigation au clavier.

Menu déroulant accessible



Description


L'un des problèmes récurrents avec les menus déroulants est qu'ils empêchent les utilisateurs de naviguer au clavier, ce qui terme d'accessibilité, n'est pas ce qu'on fait de mieux. Aussi, ce tutoriel vous montre comment procéder en alliant un code xhtml sémantique, une feuille de style css ainsi qu'un script javascript. Que ce soit sous Firefox ou IE, vous pourrez dès lors vous servir de la tabulation pour naviguer sans souris.

Codes


page xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> <title>Menu déroulant accessible</title> <link rel="stylesheet" type="text/css" media="screen" href="menu.css" /> <script type="text/javascript" src="menu.js"></script> </head> <body> <div id="menu"> <dl> <dt>Menu 1</dt> <dd><ul> <li><a href="./">Lien 1</a></li> <li><a href="./">Lien 2</a></li> <li><a href="./">Lien 3</a></li> <li><a href="./">Lien 4</a></li> </ul></dd> </dl> <dl> <dt>Menu 2</dt> <dd><ul> <li><a href="./">Lien 5</a></li> <li><a href="./">Lien 6</a></li> <li><a href="./">Lien 7</a></li> <li><a href="./">Lien 8</a></li> <li><a href="./">Lien 9</a></li> <li><a href="./">Lien 10</a></li> </ul></dd> </dl> <dl> <dt>Menu 3</dt> <dd><ul> <li><a href="./">Lien 11</a></li> <li><a href="./">Lien 12</a></li> <li><a href="./">Lien 13</a></li> </ul></dd> </dl> <dl> <dt>Menu 4</dt> <dd><ul> <li><a href="./">Lien 14</a></li> <li><a href="./">Lien 15</a></li> <li><a href="./">Lien 16</a></li> <li><a href="./">Lien 17</a></li> <li><a href="./">Lien 18</a></li> <li><a href="./">Lien 19</a></li> <li><a href="./">Lien 20</a></li> </ul></dd> </dl> <script type="text/javascript"> <!-- //Utile pour ne pas voir les éléments dd apparaître au chargement de la page var oDd=document.getElementsByTagName('dd'),i=oDd.length-1;for(i;i>=0;i=i-1)oDd[i].style.display='none'; //--> </script> </div> </body> </html>
A noter que le script en fin de menu n'est pas obligatoire et peut donc être supprimé. Il sert uniquement à ne pas afficher les menus déroulés au chargement de la page, ce qui peut gêner certains d'entre vous... A vous de voir si vous le laissez ou non. ;-)

menu.css
* { padding: 0; border: 0; margin: 0; } body { font: 100% "Times New Roman", serif; background-color: #444; color: #FFF; } #menu { position: absolute; top: 0; margin: 40px; } #menu dl { margin: 0 2px; float: left; border: 1px solid #000; width: 166px; text-indent: 10px; } #menu dl dt { font-weight: bold; font-size: .9em; line-height: 1.3em; background-color: #555; color: #DDD; } #menu dl dd { border-top: 1px solid #000; } #menu dl dd ul { list-style-type: none; border-top: 0; line-height: 1.5em; } #menu dl dt a { background-color: #555; color: #DDD; text-decoration: none; display: block; width: 166px; height: 1.3em; cursor: default; } #menu dl dd ul li { font-weight: normal; font-size: .7em; line-height: 1.5em; } #menu dl dd ul li a { width: 166px; height: 1.5em; text-decoration: none; display: block; background-color: #FFF; color: #000; text-indent: 10px; cursor: pointer; } #menu dl dd ul li a:hover, #menu dl dd ul li a:focus { background: #DDD; }

menu.js
// Raccourci et création d'un objet var d = document, o = {}; // Définition des propriétés de l'objet o.Menu = { // Chargement du menu __Load__: function() { // On lance le test pour s'assurer du bon fonctionnement o.Menu.__Test__(); }, // Test d'existence des méthodes et de la syntaxe xhtml __Test__: function() { // Si l'une des méthodes du script n'est pas interprétée ou si le menu n'existe pas, on stoppe le script. if ( !d.getElementById || !d.getElementsByTagName || !d.createElement || !d.createTextNode || !d.getElementById('menu') || !d.getElementById('menu').setAttribute || !d.getElementById('menu').replaceChild || !d.getElementById('menu').appendChild || !d.getElementById('menu').getElementsByTagName('dl') ) return false; /* ----- Tests facultatifs et non exhaustifs de bon augure ^^ ----- ----- Les codes contenus dans la zone suivante peuvent ----- ----- être virés si vous êtes sûr de votre syntaxe xhtml. ----- */ // Une fois le premier test effectué, on définit les variables nécessaires. var iA, iB, iC, iD, oMenu = d.getElementById('menu'), oDl = oMenu.getElementsByTagName('dl'); // Pour chaque élément dl du tableau oDl, for ( iA = oDl.length - 1; iA >= 0; iA-- ) { // on récupère les éléments dt dans un tableau. var oDt = oDl[iA].getElementsByTagName('dt'); // Si le tableau oDt est vide, on stoppe le script. if ( !oDt ) return false; } // Pour chaque élément dl du tableau oDl, for ( iA = oDl.length - 1; iA >= 0; iA-- ) { // on récupère les éléments dd dans un tableau oDd. var oDd = oDl[iA].getElementsByTagName('dd'); // Si le tableau oDd est vide, on stoppe le script. if ( !oDd ) return false; // sinon else { // pour chaque élément dd du tableau oDd, for ( iB = oDd.length - 1; iB >= 0; iB-- ) { // on récupère les éléments ul dans un tableau oUl. var oUl=oDd[iB].getElementsByTagName('ul'); // S'il n'y a pas d'élément ul, on stoppe le script. if( !oUl ) return false; // sinon else { // pour chaque élément ul du tableau oUl, for ( iC = oUl.length - 1; iC >= 0; iC-- ) { // on récupère les éléments li dans un tableau oLi. var oLi = oUl[iC].getElementsByTagName('li'); // S'il n'y a aucun objet oLi, on stoppe le script. if( !oLi ) return false; // sinon else { // pour chaque élément li du tableau oLi, for ( iD = oLi.length - 1; iD >= 0; iD-- ) { // on récupère l'élément a dans un objet oA. var oA = oLi[iD].getElementsByTagName('a')[0]; // S'il n'y a pas d'objet oA, on stoppe le script. if( !oA ) return false; } } } } } } } /* ----- ----- ----- Fin des tests facultatifs de bon augure ^^ ----- ----- ----- */ // Une fois le test effectué, on initialise le menu. return o.Menu.__Init__(); }, // Méthode d'initialisation du menu __Init__:function() { // On définit les variables nécessaires. var iA, oMenu = d.getElementById('menu'), oDl = oMenu.getElementsByTagName('dl'); // On cache tous les éléments dd en lançant la méthode dédiée à cette tâche. o.Menu.__HideLists__(); // Pour chaque élément dl du tableau oDl, for ( iA = oDl.length - 1; iA >= 0; iA-- ) { // On récupère l'élément dt. var oDt = oDl[iA].getElementsByTagName('dt')[0]; // On crée un élément dt et un élément a var oNewDt = d.createElement('dt'), oA = d.createElement('a'), oTextA = d.createTextNode(''); // On définit les propriétés de l'objet oA // (récupération du noeud texte de l'élément dt pour définir celui de l'élément a) oA.setAttribute('href','#'); oTextA.data = oDt.firstChild.nodeValue; // On constitue l'arbre DOM en remplaçant l'élément dt du code xhtml // par celui qu'on vient de créer. oA.appendChild(oTextA); oNewDt.appendChild(oA); oDl[iA].replaceChild(oNewDt,oDt); // On définit des méthodes en fonction des actions de l'utilisateur. oA.onclick = o.Menu.__Discard__; oDl[iA].onmouseover = o.Menu.__MouseDisplay__; oA.onfocus = o.Menu.__TabDisplay__; oA.onkeypress = o.Menu.__TabDisplay__; } }, // Méthode d'affichage de l'élément dd lorsqu'on le survole. __MouseDisplay__:function() { // On cache tous les éléments dd en lançant la méthode dédiée à cette tâche. o.Menu.__HideLists__(); // On récupère l'élément dd de l'élément dl qu'on survole dans un objet. var oDd = this.getElementsByTagName('dd')[0]; // On affecte la propriété css "display: block;" à l'objet oDd (affichage) oDd.style.display = 'block'; // On cache l'élément dd lorsqu'on ne survole plus l'élément dl. this.onmouseout = o.Menu.__HideLists__; }, // Méthode d'affichage de l'élément dd lorsqu'il prend le focus. __TabDisplay__:function() { // On cache tous les éléments dd en lançant la méthode dédiée à cette tâche. o.Menu.__HideLists__(); // On récupère l'élément dd de l'élément dl qui a le focus dans un objet. var oDd = this.parentNode.parentNode.getElementsByTagName('dd')[0]; // On affecte la propriété css "display: block;" à l'objet oDd (affichage) oDd.style.display = 'block'; // On donne le focus au premier lien de l'élément dd traité. oDd.getElementsByTagName('a')[0].focus(); }, // Méthode de masquage des éléments dd __HideLists__:function() { // On définit les variables nécessaires. var iA, oDd = d.getElementById('menu').getElementsByTagName('dd'); // Pour chaque élément dd du tableau oDd, for (iA = oDd.length - 1; iA >= 0; iA-- ) { // On affecte la propriété css "display: none;" à l'objet oDd (masquage) oDd[iA].style.display = 'none'; } }, // Fonction d'annulation __Discard__:function() { // On annule l'action. return false; } }; // Une fois que le document est chargé en mémoire, on charge le script. window.onload=o.Menu.__Load__;

visualiser

En suivant le lien de visualisation, vous trouverez le code tel que présenté dans ce tuto (avec commentaires et tests facultatifs) ainsi qu'une version de développement (sans commentaires et avec tests facultatifs) et une dernière optimisée (sans commentaires, sans tests facultatifs et compressée).

ACCÉS COMMUNAUTÉ

Rejoignez ALL HTML

Publiez vos articles, actualités, communiqués ... Donnez votre avis, partagez votre réseau, rencontrez d'autres membres et participez à la vie de la communauté.