Ajax et accessibilité : attention
Par Laurentj le mercredi, septembre 14 2005, 13:39 - Technologies Web - Lien permanent
Si on veut utiliser Ajax sur un site web, comme sur un blog, il faut faire attention à l'utiliser correctement. En effet, mal utilisé, un site peu devenir totalement inaccessible. Prenons donc l'exemple d'un blog ;-), affichant la liste des billets, avec pour chacun le chapô, et un lien "lire la suite" pour voir le contenu. Imaginons qu'en cliquant sur ce lien, cela ne n'affiche pas une nouvelle page, mais execute un script qui va aller chercher le texte sur le serveur, l'insérer à la suite du chapô, et l'afficher. Un exemple court et simple serait de faire :
<a href="#" onclick="afficheContenu(); return false;">Lire la suite</a>
Ça fonctionne trés bien et c'est trés agréable pour l'internaute "classique" que je suis. Mais pour les autres non. À cause du #. Pas de lien. Cela devient trés génant par exemple, pour ceux qui ont le javascript désactivé, ou qui n'ont pas du tout javascript comme ceux utilisant les navigateurs textes, ou les robots d'indexations. Et ceux utilisant par exemple des lecteurs vocaux d'écran, cela pose certainement problème. J'aimerais d'ailleurs savoir comme réagit un tel système face à une page qui est modifiée dynamiquement. Avertit-il l'internaute qu'elle a été modifiée ? prend-t-il en compte les éléments de la page ajoutés ou supprimés dynamiquement ?
Donc si on veut être sûr de pouvoir rendre accessible sa page web à tout le monde, il faut toujours renseigner les liens avec des vrais urls, faire toujours en sorte que l'internaute puisse accéder au contenu via le principe de base du web : le lien hypertexte.
<a href="/blog/2005/09/14/les-travers-d-ajax" onclick="afficheContenu(); return false;">Lire la suite</a>
Ainsi, ici, si le onclick n'est pas executé pour une raison ou une autre, le navigateur affichera la page indiquée par le lien, censée contenir donc le billet entier. Dans le cas contraire, le script sera executé, et le lien non suivi grâce au return false.
L'inconvénient de la technique, c'est qu'il faut avoir deux entrées ou page sur son site : une qui affiche le contenu du billet (/blog/2005/09/14/les-travers-d-ajax), l'autre qui propose le service web permettant de récupérer le contenu via un script javascript. Mais en ayant sur le serveur une API simple et efficace comme dans dotclear, c'est un inconvénient tout relatif ;-)
Commentaires
Je me posais justement les mêmes questions pour mon propre site, mais j'étais arrivé à un niveau supplémentaire de séparation contenu / comportement, avec aucune action javascript en dur au niveau de chaque lien, et un script lancé uniquement à la fin du chargement de la page, pour ajouter ces actions.
Le problème de l'accessibilité via des synthèses vocales des sites "ajaxisés" reste cependant à couvrir, comme tu le soulignes.
Je précise que je mettais surtout le point sur le contenu du href. Que le onclick soit dans le lien ou ajouté dynamiquement via JS ne change pas le problème si le href contient seulement #.
On peut aussi envisager d'avoir des
onclicksur des éléments autres quea. Dans ce cas pas de confusion, il s'agit simplement d'une action.Le problème de l'accessibilité reste entier, voire amplifié, sauf que le fallback est évident : si JS est désactivé, ça ne fonctionne pas.
Mais si on a utilisé CSS, une pseudo-classe :hover par exemple, pour signifier qu'une action est possible à cet endroit, on induit l'utilisateur en erreur.
Ce qui revient peut-être à se poser la question : est-il justifié d'utiliser des « liens » pour éxécuter une action autre qu'activer un hyperlien ? Quelles sont les autres options ?
Une autre option peut être, à l'instar de Nicolas, de rajouter des éléments (liens, textes), leurs styles et les comportements associés _après_ le chargement de la page : pas de javascript, pas de problème : la page reste accessible puisque fonctionnelle en HTML de toutes façons.
Juste en passant pour l'accessibilité justement, un lien "lire la suite" n'est vraiment pas ce que l'ont fait de mieux ;)
J'aurais une toute petite amélioration à suggérer sur le code : il n'est pas impossible que JavaScript soit bien activé, mais que l'appel à
afficheContenu();échoue pour une raison ou pour une autre (un navigateur pourrait ne pas comprendre ou bloquer ces requêtes).Pour garantir que le lien fonctionne pour tous, si on imagine que
afficheContenu();retournetruequand l'appel a fonctionné, on pourrait utiliser :<a href="/blog/..." onclick="return !afficheContenu();">Lire la suite</a>.Comme cela on n'empêche pas la remontée de l'événement (et donc de suivre le lien donné en
href) si l'étape Ajax échoue.Bonjour
Je suis défficients visusl, webmaster et travaille avec jaws,
Je viens d'essayer le lien avec comme adresse le # avec jaws, il est lu normalement, pas de problèmes, vu que la synthèse vocale ne prenonce jamais l'adresse d'un lien, mais uniquement le mot lien et son contenu, dans le cas qui nous concerne elle dit lien lire la suite, par contre il est essentiel pour moi qui ne vois pas que le onclick sois associé a un lien, sinon il n'y a rien pour m'indiquer que le texte es clicable.
Il es vrai aussi que les liens lire la suite ne sont pas trop accessible, je préffère que le titre du billet sois unlien et qu'il affiche le billet, car quand on liste les liens de la page si on se retrouve avec une 20ène de liens lire la suite, ce ne sera pas pratique, allors qu'avec les titres des billets en lien, ce sera beaucoup plu facile d'aller lire directement le bon billet.
Merci Luc de me donner des billes, je me doutais que ça devais pas trop mal se passer avec Jaws. J'ai oublié de mettre le title dans "lire la suite" je vais l'ajouter. Sinon Laurent, indicible est un labo, pas un site qui a la vocation d'être intéressant. Il n'est pas indexé, ne cherche pas le visiteur et est fait pour essayer des trucs un peu borderline et j'assume ceci parfaitement.
Olivier, c'est ce que je me doutais te connaissant (un peu :-). J'ai surtout écris ce billet pour faire prendre conscience aux autres développeurs qu'il faut faire attention à l'usage d'Ajax...
Et en utilisant la balise <noscript></noscript>? Si le js est désactivé on affiche une solution sinon on affiche l'autre solution (Ajax).