Javascript non-intrusif, chapitre 1 : le grand nettoyage !

Par Christian Heilmann

Cet article est le premier d'une série qui en compte 5.

Le Javascript est un formidable outil pour améliorer l'utilisabilité des sites web. C'est une couche supplémentaire au dessus du balisage « qu'est-ce qu'est ce texte » et du CSS « comment doit-il être affiché » qui ajoute une nouvelle dimension, le « comment cet élément doit-il se comporter».

Dans les pages suivantes nous allons voir comment utiliser Javascript tout en continuant de maintenir l'accessibilité. La technique utilisée pour séparer complètement le Javascript des deux autres couches de développement web est désormais communément appelée le « Javascript non-intrusif », dans la mesure où « Javascript accessible » ne convenait pas tout à fait puisque vous pouvez avoir un Javascript parfaitement séparé et rester complètement inaccessible.

Mais bon, cessons les bavardages et mettons nous au travail.

Ces dernières années, le développement web a subi un changement majeur : nous avons appris à séparer la présentation et la structure, simplifiant ainsi les processus de relookage en n'intervenant plus que sur une feuille de style centralisée.

On peut aller encore plus loin dans la séparation, en n'utilisant plus de styles en ligne (NdT : on a un mot pour ça en français ?) ni de classes, mais en se basant sur les héritages et les sélecteurs contextuels.

Ainsi...

HTML:
<table border="0" cellpadding="0" width="100%" cellspacing="5">
<tr>
<td><font face="Arial" size="-2">Lorem Ipsum</font></td>
</tr>
</table>

... est devenu :

CSS:
td.content {font-family:Arial,sans-serif;font-size:12px;}
HTML:
<table cellpadding="0" style="width:100%;border:none" cellspacing="5">
<tr>
<td class="content">Lorem Ipsum</td>
</tr>
</table>

... puis finalement :

CSS:
body {font-family:Arial,sans-serif;font-size:12px;}
p {padding:5px;}

HTML:
<p>Lorem Ipsum</p>

La même évolution peut et doit avoir lieu en ce qui concerne le Javascript.

Sortons le Javascript de la page

La première règle du club Javascript non-intrusif, c'est de ne pas parler du club Javascript non-intrusif. Euh non, attendez, je m'égare... c'est :

1. Jamais, au grand jamais, vous ne devez insérer de Javascript directement dans le document

Une des grandes forces du Javascript est d'être stocké dans un fichier à part. Tout comme avec les CSS, cela signifie que vous pouvez appliquer une collection de fonctions à chaque page de votre site, et si vous devez changer une fonctionnalité, vous pourrez le faire dans un document unique plutôt que de parcourir toutes vos pages.

Ce qui veut dire que, sauf circonstances exceptionnelles, tout ce que nous devons voir dans un document HTML se résume à :

<script type="text/javascript" src="scripts.js"></script>

Nous n'avons besoin que de cette ligne, et plus d'aucun Javascript imbriqué. Apprenez cette dernière phrase par cœur.

2. Le Javascript permet d'améliorer l'expérience de l'utilisateur, ce n'est cependant pas une fonctionnalité fiable à 100%

Nous n'utilisons le Javascript que pour améliorer une fonctionnalité qui existe déjà, nous ne nous appuyons pas dessus. Le Javascript peut être désactivé, ou filtré par les proxies et les pare-feux des sociétés férues de sécurité. On ne peut jamais partir du principe qu'il fonctionnera toujours.

Ce qui ne veut pas dire que nous ne pouvons pas utiliser de Javascript ; cela signifie simplement que nous devons l'intégrer de manière optionnelle plutôt que comme un prérequis.

HTML:
<form action="index.php" onsubmit="return checkform(this)">
  <p>
    <label for="login">Identifiant :</label>
    <input type="text" name="login" id="login" />
  </p>
  <p>
    <label for="pw">Mot de passe :</label>
    <input type="password" name="pw" id="pw" />
  </p>
  <p>
    <input type="submit" value="send" />
  </p>
</form>

Javascript:
function checkform(f)
{
  var error='';
  error+=f.login.value==''?'\nlogin':'';
  error+=f.pw.value==''?'\npassword':'';
  if (error!='')
  {
    alert('Veuillez saisir le(s) champ(s) suivant(s) :'+error);
  }
  return error=='';
}

Le code ci-dessus est parfaitement valide, et évitera que les utilisateurs ne subissent un aller-retour vers le serveur s'ils oublient de saisir une valeur.

HTML:
<form action="index.php">
  <p>
    <label for="login">Identifiant :</label>
    <input type="text" name="login" id="login" />
  </p>
  <p>
    <label for="pw">Mot de passe :</label>
    <input type="password" name="pw" id="pw" />
  </p>
  <p>
    <input type="button" onclick="checkform()" value="Envoyer" />
  </p>
</form>

Javascript:
function checkform()
{
  var f=document.forms[0];
  var error='';
  error+=f.login.value==''?'\nlogin':'';
  error+=f.pw.value==''?'\npassword':'';
  if (error!='')
  {
    alert('Veuillez saisir le(s) champ(s) suivant(s) :'+error);
  } else {
    f.submit();
  }
}

On pourrait croire que c'est la même chose, mais un détail change : si le Javascript est désactivé, le bouton ne réagira plus du tout, malgré les clics répétés de l'utilisateur frustré ! Répétons-le : on ne peut pas se fier au Javascript, ne nous appuyons pas dessus !

3. Vérifiez qu'un objet est disponible avant de le manipuler

Bon nombre d'erreurs Javascript arrivent pour la simple raison que le développeur n'a pas pris la peine de tester si une méthode ou un objet est ou non disponible.

Javascript:
function color(o,col)
{
  o.style.background=col;
}

Le code ci-dessus peut échouer et provoquer une erreur Javascript si l'objet o n'est pas disponible... alors que celui-ci marchera à tous les coups :

Javascript:
function color(o,col)
{
  if(o)
  {
    o.style.background=col;
  }
}

Cette technique est utilisée le plus souvent pour vérifier qu'un navigateur sait gérer telle ou telle fonctionnalité Javascript. À l'époque où nos développements se faisaient encore à tâtons (on s'en moquait, on était payés, soit par le client soit par la startup qui nous employait), ces tests se faisaient en détectant les navigateurs (NdT : browser sniffing), un concept voué à l'échec dès le départ : chaque fois qu'un nouveau navigateur sortait ou était mis à jour, il fallait réécrire le script de détection. De nos jours, il est généralement nécessaire de tester si le navigateur est capable de comprendre le modèle d'objet document du W3C[1] (DOM[2]), ce qui nous amène à la règle suivante.

4. Écrivez du Javascript, et pas un dialecte particulier à un navigateur

À moins qu'il n'y ait une bonne raison de le faire, nous ne devrions jamais utiliser des extensions spécifiques à un (ou des) navigateur(s) au lieu des standards du web. L'époque où nous vérifiions document.layers (Netscape 4.x) ou document.all (Internet Explorer < 5) est révolue. Les navigateurs modernes comprennent la méthode document.getElementById issue du DOM, et c'est donc ces méthodes que nous utiliserons et que nous testerons.

Javascript:
function unTrucEnDOM()
{
  if(document.getElementById && document.createTextNode)
  {
    [...]
  }
}

La deuxième vérification n'est nécessaire que parce que certaines versions précédentes d'Opera annonçaient qu'elles comprenaient le DOM, alors qu'elles ne savaient pas l'utiliser comme il fallait.

5. N'utilisez pas des variables qui ne vous appartiennent pas

En écrivant une fonction ou une méthode, nous devons nous assurer que toutes les variables utilisées sont locales, pour éviter qu'une fonction ne modifie une variable utilisée par une autre fonction.

Javascript:
var i=42; // variable globale

function faisUnTruc()
{
  for (i=0;i<200;i++) // i change
  {
    // du code
  }
}

function faisBienLesChoses()
{
  var i; // i est définie localement
  for (i=0;i<200;i++)
  {
    // du code
  }
}

alert(i); // = 42
faisBienLesChoses();
alert(i) // = 42 (puisque c'est une définition locale)
faisUnTruc();
alert(i) // = 200, oulà!

6. Ne soyez pas dépendant de la souris !

S'assurer que les choses marchent quand le Javascript est activé n'est pas encore suffisant. Nous devons aussi être attentifs aux visiteurs qui n'utilisent pas de souris, ou avec difficulté. Nous devons donc nous assurer que tous les effets seront déclenchés aussi bien par la souris que par le clavier.

Le plus gros problème pour se libérer de la souris vient souvent des éléments de formulaires qui sont validés ou qui déclenchent une action quand ils changent (onchange) ou quand on les quitte (onblur). Ne vous en servez pas, c'est aussi simple que ça !

Par exemple cette méthode inaccessible est très répandue pour détourner les listes déroulantes et en faire des artefacts de navigation :

HTML:
<form>
<p>
  <label for="go2">Aller à:</label>
  <select name="go2" id="go2" onchange="envoyer(this)">
  <option value="index.html">Accueil</option>
  <option value="chapter1.html">Chapitre 1</option>
  <option value="chapter2.html">Chapitre 2</option>
  </select>
</p>
</form>

Javascript:
function envoyer(f)
{
  var monChoix;
  monChoix=f.options[f.selectedIndex].value;
  self.location=monChoix;
}

Testez cet exemple de liste déroulante non accessible.

Dans les faits, si vous utilisez un clavier et que vous tabulez jusqu'à cet élément de formulaire, tapez flèche bas pour faire votre choix, vous n'irez jamais plus loin que la première option, puisque la fonction envoyer() est déclenchée quand vous passez de la première à la deuxième option.

Les utilisateurs experts du clavier savent qu'il faut taper alt + flèche bas auparavant, pour dérouler la liste avant de faire son choix.

Cependant, cette méthode n'est pas connue de tous. De plus, cet exemple ne fait rien si le Javascript n'est pas activé.

HTML:
<form action="send.php" method="post" onsubmit="return envoyer(this)">
<p>
  <label for="go2">Aller à:</label>
  <select name="go2" id="go2">
    <option value="index.html">Accueil</option>
    <option value="chapter1.html">Chapitre 1</option>
    <option value="chapter2.html">Chapitre 2</option>
  </select>
  <input type="submit" value="hop !" />
</p>
</form>

Javascript:
function envoyer(f)
{
 var monChoix;
 monChoix=f.go2.options[f.go2.selectedIndex].value;
 self.location=monChoix;
 return false;
}

PHP:
<?php
if(isset($_POST['go2'])){
 header('Location:'.$_POST['go2']);
}
?>

Testez cet exemple de liste accessible.

Au contraire de tout à l'heure, cet exemple fonctionne sans souci, et nous épargne un aller-retour au serveur vers send.php, qui n'est utilisé que si le Javascript est désactivé.

Que penser de onkeypress ?

En parcourant les Règles d'Accessibilité des Contenus Web[3], on nous demande de n'invoquer que des gestionnaires d'événements indépendants des interfaces d'entrée dans nos scripts :

Sinon, si vous devez utiliser des attributs dépendant d'interfaces particulières, fournissez des mécanismes d'entrée redondants (par exemple, spécifiez deux gestionnaires d'événements pour le même élément) : utilisez « onmousedown » avec « onkeydown ». Utilisez « onmouseup » avec « onkeyup ». Utilisez « onclick » avec « onkeypress ».

Tout cela a l'air parfait, en théorie, mais dans la vie réelle, l'événement onkeypress est assez mal géré par les différents navigateurs. Des utilisateurs dépendant de leur clavier pour surfer ont habituellement configuré une touche pour simuler le clic, soit la touche entrée soit la barre d'espace, et ces deux touches déclenchent l'événement onclick. En utilisant onkeypress nous risquons d'intercepter d'autres fonctionnalités du clavier dont l'utilisateur avait besoin. Quelques exemples : la fonction « type ahead »[4] de Mozilla, les raccourcis étendus d'Opera[5] (comme « A » pour aller au lien suivant) ou les contrôles au clavier de JAWS[6].

Autrement dit, en nous conformant aux Règles d'accessibilité, nous risquons de rendre notre script encore plus inaccessible.

Dans les exemples qui suivront dans ces leçons, nous ajouterons onkeypress en tant que gestionnaire supplémentaire, mais nous le laisserons en commentaire. Il s'agit juste de vous permettre de l'activer le cas échéant, par exemple si vous devez subir un audit d'accessibilité fait par des outils automatisés plutôt que par des humains.

Liens

» À suivre : « Javascript non-intrusif, chapitre 2 : comment retrouver les éléments que l'on veut manipuler ».

Fiche technique

À propos de l'auteur

lang="en">Christian Heilmann
est un contributeur de Digital Web Magazine. La plupart de ses
publications sont écrites dans le métro, en voyageant
à travers Londres, parce qu’il n’y a simplement rien d’autre
à y faire. Un jour il aimerait remettre son propre livre
à ceux qui sont coincés là.

Articles du même auteur

Articles similaires

Voici la liste des dix articles les plus récents en rapport avec cet article :

Intermédiaire

JavaScript

© 2001-2016 Pompage Magazine et les auteurs originaux - Hébergé chez Nursit.com ! - RSS / ATOM - About this site