La problématique
Pourquoi une navigation en Ajax ?
Une navigation en Ajax a les avantages suivants par rapport à une navigation HTML standard :
- pas de rechargement complet de la page, seul le contenu demandé est chargé, ce qui permet de gagner au niveau du temps de traitement de la page et de la bande passante utilisée.
- possibilité d’avoir des effets de transition entre chaque chargement de page
- permet d’éviter l’utilisation de frames
Au final, ces avantages permettent d’avoir une navigation plus rapide, plus performante et plus agréable visuellement. Cependant, d’autres problématiques apparaissent de fait :
- Le site ne pourra plus fonctionner sans Javascript ce qui est au détriment de l’accessibilité (Accessibilité du Web). De plus, le référencement du site ne fonctionnera pas vu que les robots d’indexations des moteurs de recherches ne se servent pas du Javascript pour naviguer de lien en lien.
- Le contenu courant de la page n’est plus lié à son URL
- le bookmark d’une page du site ne correspond plus au contenu.
- l’historique de navigation ne fonctionne plus.
De plus, une notion de décoration (ou d’habillage) de page apparaît. En effet, la première page appelée chargera tout le site (avec décoration), cette page contiendra tout le Dom HTML, balises <head/>
pour le chargement des CSS et du JS, balise <body>
pour le chargement d’un menu de navigation et enfin du contenu de la page.
Les chargements des pages suivantes seront sans décoration, c.-à-d. qu’ils ne chargeront que le contenu du site. Il faut donc trouver un système permettant de distinguer ces 2 types de chargement.
La théorie
Les 3 problèmes identifiés sont :
- la navigation doit être possible en mode dégradé, c’est-à-dire sans Javascript
- le contenu des pages doit être lié à l’url courante
- la gestion de l’habillage des pages
Permettre une navigation dégradée
Les liens de la navigation seront générés avec des liens standards <a/>
dont les attributs href mèneront vers les contenus, ie <a href=’/ma_categorie/contenu.html’/>
.
Ceci permettra aux robots d’indexation de naviguer de lien en lien dans le site permettant le référencement de celui-ci.
De plus, les liens <a/>
participant à la navigation Ajax devront comporter un élément distinctif par rapport à des liens externes. Dans notre exemple, nous ajouterons l’attribut rel='history'
.
Lier le contenu à l’URL
L’utilisation d’ancres permet de modifier la valeur d’une URL sans provoquer un rechargement de page. L’utilisation habituelle des ancres permet de faire des liens internes à une page (ie. très utilisé dans un wiki).
Une url sera de la forme : http://serveur.fr/#/categorie/contenu.html
.
Pour lier notre contenu à l’URL, il est nécessaire :
- de surcharger l’événement clic qui aura pour effet de mettre à jour l’ancre dans l’URL du navigateur
- de détecter un changement de la valeur de l’ancre et faire la requête Ajax retournant le contenu de la page demandée
Dans le cas où un utilisateur rentre directement une URL complète sans ancre (ie. provenant d’un moteur de recherche), il faut prévoir une redirection vers la racine du site et en ajoutant dans l’ancre le contenu demandé (ie. http://serveur.fr/#/categorie/contenu.html
).
Cette redirection devra se faire en JS et non côté serveur sinon le référencement et l’accessibilité seront perdus.
Ceci permet d’éviter d’avoir des URL de ce genre : http://serveur.fr/categorie/contenu2.html#/categorie/contenu.html
.
Ce qui donne :
-# clic sur un lien ou sur le bouton retour/suivant du navigateur
-# si le lien ne contient pas d’ancre, redirection vers la racine et ajout de l’ancre correspondant au contenu demandé
-# modification de l’ancre
-# détection du changement de valeur de l’ancre
-# appel Ajax permettant de charger le contenu (sans décoration)
-# traitement JS insérant le contenu
Décorer ses contenus
L’appel Ajax qui chargera le contenu devra utiliser un mot clé dans la requête Ajax permettant de distinguer sans décoration. Par exemple : http://serveur.fr/ajax/categorie/contenu.html
.
Pour résumer ces 3 points, voici 2 exemples de chargement de la page http://serveur.fr/categorie/contenu.html
avec et sans Javascript.
Avec Javascript :
-# Appel à http://serveur.fr/categorie/contenu.html
depuis le navigateur
-# redirection de l’url vers http://serveur.fr/#/categorie/contenu.html
-# chargement avec décoration de la page http://serveur.fr/
(ne contient pas le mot clé de décoration, ici, ajax)
-# appel de l’ancre #/categorie/contenu.html
(détecté par le script)
-# chargement en Ajax sans décoration de la page http://serveur.fr/ajax/categorie/contenu.html
Sans Javascript :
-# Appel à http://serveur.fr/categorie/contenu.html
depuis le navigateur
-# chargement avec décoration de la page http://serveur.fr/categorie/contenu.html
La mise en œuvre avec jQuery
Coté Javascript, jQuery a été choisi (cf. Fiche jQuery) pour sa multitude de plugin et son évolutivité.
- Javascript non intrusif
- facilité d’écriture
- gestion des ancres
- détection du changement d’URL
- gestion de l’historique
L’intégration du plugin history se fait en 3 étapes :
- Définir une fonction pageload(), le paramètre est la valeur de l’ancre
function pageload(hash) <em>if(hash) {
// mon appel Ajax
</em>
}
- Initialiser le plugin history
$(document).ready(function()<em>$.historyInit(pageload) ;
</em>) ;
- Surcharger les clics des liens à chaque appel Ajax
$(document).ajaxComplete(function()<em>// sélection de tous les liens a ayant l'attribut rel égal à history (valeur arbitraire)
$("a<a href="http://noregret.org/tutor/navigation/test/iemagic1.html">@rel='history']").click(function(){
//suppression du mot cle history, pour que les liens ne soient surchargés qu'une seule fois
this.rel = this.rel.replace(/history/, '') ;
// mise à jour de l'ancre
var hash = this.href ;
// suppression du caractère #
hash = hash.replace(/^.*#/, '') ;
// chargement dans l'historique et appel de pageload
$.historyLoad(hash) ;
// trés important : désactivation du clic du lien a
return false ;
</em>) ;
}) ;
Gestion de l’habillage
Concernant la gestion de l’habillage (qui s’exécute coté serveur), plusieurs choix de bibliothèques sont disponibles suivant le langage utilisé. On pourra, par exemple, utiliser Struts Tiles pour Java.
Problèmes rencontrés
IE6 et flash
Si vous utlisez cette navigation à travers un flash (qui appelera votre JS), il est possible de rencontrer ce problème sous Internet Explorer : [. Au bout de quelques clic, IE devient blanc.
La solution est de modifier l’appel JS depuis le flash en n’utilisant pas getUrl mais FsCommand.
IE6 et le symbole ‘ ?’
IE6 ne supporte pas d’avoir le symbole ‘ ?’ dans l’ancre. Il faudra prévoir de le remplacer par un autre caractère (ie. ‘_’) dans ce cas, ce qui donne :
- sans ancre :
http://serveur.fr/categorie/contenu.html?param=true
- avec ancre :
http://serveur.fr/#/categorie/contenu.html_param=true
Exemple
Conclusion
Avec les techniques Ajax et les plugins JS comme jQuery, la navigation Ajax se fait d’une manière transparente et performante tout en laissant la possibilité d’une navigation standard sans Javascript.
YoTsumi
13 mai 2008
Si vous voulez voir un autre exemple, je me permets de vous passer l’adresse d’un blog que j’ai conçu et respectant ces principes ( de manière un peu plus artisanale/’bourine’ cependant ! )
Le blog
Remarquès
15 mai 2008
Le site Dior dit « hors » à Firefox, qui plante brutalement.
Godefroy (Skreo)
21 mai 2008
Article très intéressant, merci :-)
Je vais améliorer la navigation Ajax d’EklaBlog.com en utilisant les ancres. Le seul problème dans la navigation actuelle est que l’url de la page ne change pas, ce qui est très gênant pour certains utilisateurs.
Joe
18 juin 2008
Fonctionne très bien… sauf sous IE7 qui n’inclut pas les ancres dans l’historique !
truf
13 juillet 2008
Salut,
Je rencontre cette problématique et lis donc votre article avec interêt.
Je ne comprend pas ce passage :
« Dans le cas où un utilisateur rentre directement une URL complète sans ancre (ie. provenant d’un moteur de recherche), il faut prévoir une redirection vers la racine du site et en ajoutant dans l’ancre le contenu demandé (ie. http://serveur.fr/#/categorie/contenu.html). » Cette redirection devra se faire en JS et non côté serveur sinon le référencement et l’accessibilité seront perdus. Ceci permet d’éviter d’avoir des URL de ce genre : http://serveur.fr/categorie/contenu2.html#/categorie/contenu.html.
Ce n’est pas justement l’inverse? Une redirection en .js ne serait pas interprété, alors qu’une url rewriting etc. le serait.
(cf. http://www.webrankinfo.com/referencement/liens/redirections.php).
Guillaume Saint-Raymond
16 juillet 2008
Bonjour,
La redirection se fait coté client afin de pouvoir respecter la navigation dégradée (sans Javascript).
En effet, dans le cas où Javascript n’est pas interprété, il ne faut pas que l’URL soit redirigée avec l’URL contenu présent dans l’ancre (ie. http://serveur.fr/#/categorie/contenu.html) car, dans ce cas, la navigation afficherait tout le temps la page d’index du serveur (http://serveur.fr/) quel que soit le contenu (l’ancre n’étant pas interprété).
Emile_le_roux
25 juillet 2008
Bonjour,
Quelqu’un connaitrait-il un moyen d’appliquer cette méthode sur IE ?
En effet, il n’intègre pas l’hash dans l’historique mais j’ai vu des sites qui y arrive ! (sans comprendre le code source bien évidemment…)
Merci !
yassine samadi
12 octobre 2008
Merci pour ce document,
j’ai essayé de faire la même chose que l’exemple jQuery history (j’ai fait copier coller du code de la page et ce lui des deux fichier js) et ça marche pas et je sais pas pour quoi, est ce qu’il faut changer quelques choses : http://www.crea-soft.net/jquery_history.html/ merci de vérifier !
cette technique va m’aider énormément pour dépasser les problèmes rencontrer avec AJAX essentiellement pour le site motorzone.ma
Merci
yassine samadi
12 octobre 2008
je viens de comprendre grâce à un ami qu’il faut mettre dans le même répertoire des fichiers html (1.html, 2.html…).
c’est très bien, mais ma méthode de travail consiste à appeler une fonction js : sendMultiData (‘param1′,’param2′,’param3’)
avec :
et la liste de tout mes fonctions se trouve dans un fichier ‘function.php’.
ça semble bizard mais c’est très pratique, j’ai développé des portails comme ça.
ce que que je compte faire avec cette technique c’est de tracer un tableau Js dont je vais affecter pour chaque lien ancre une liste des paramètre de ma fonction sendMultiData. comme ça je profite de cette technique et de ce que j’ai développer en Ajax.
mais vu que j’ai pas compris très bien ce code, je sais pas qu’est ce qu’il faut remplacer par mon tableau. quelqu’un peut m’aider !?
pige
19 février 2009
Bonjour,
Depuis peu, j’ai une ancre qui s’inscrit dans une url lors de la navigation. J’aimerai savoir comment supprimer cette ancre (#)
Merci pour votre aide.
dev211
20 février 2009
un petit exemple serait possible SVP pour bien comprendre ? merci
Mika1234
7 avril 2009
Pourrions nous avoir un petit exemple s’il vous plait (comment écrire nos liens, la page ajax, la page php (contenu).
Un grand merci
Xavier
23 avril 2009
Bonjour et merci pour cet article. Si les liens sont remplacés par des ancres, la navigation sans javascript ne peut être possible non ?
Nicedude
26 août 2009
Ben si, vu que les liens sont modifiés en ancre en javascript.
Donc pas javascript, pas de redirection
pas de redirection, pas d’ancre
pas de palais, pas de palais
Renan
19 octobre 2009
Bonjours
Votre solution me semble très correcte.
Cependant que se passe-t-il lorsqu’un utilisateur avec JS publie un lien vers une page du site (Avec l’ancre dans l’url), et qu’un internaute sans JS suis ce lien ?
Il se retrouvera sur la page d’accueil et ne sera pas redirigé c’est bien ça ? Donc il n’est pas plus avantagé que si on n’avait pas fait attention aux utilisateurs sans JS.
Et les liens déposés par des utilisateurs JS ne créent pas non plus de liens profonds niveau référencement ! Juste un lien vers la page de base, avec une ancre non prise en compte par google.
Bien sur la solution que vous proposez est intéressante, mais il reste des points négatifs.
La solution parfaite n’existe peut être pas en fait ^^.
Guillaume Saint-Raymond
20 octobre 2009
Renan : Les points que tu soulèves sont justes, ce sont les limitations de l’utilisation de la navigation Ajax mise en place ici.
Concernant le référencement et les ancres, il semblerait que la donne soit en train de changer : http://s.billard.free.fr/referencement/?2009/10/08/571-google-propose-une-methode-pour-le-referencement-des-sites-ajax
fce
10 octobre 2010
Merci de m’avoir orienter vers ce plugin qui est génial.
Par contre à votre place j’encoderai l’url comme sa il n’y a plus de soucis avec le ? vu qu’il devient %3f
Gab
3 août 2011
Ce serait cool de voir comment implémenter cela avec le plugin jQuery address et WordPress.
juju
20 novembre 2012
Bonjour,
Cet article a été le premier sur lequel je me suis documenté avant de commencer à développer un outil web qui va gérer premièrement des modules dotés de contrôleurs ayant eux même des fonctions que l’on pourra appeler en ajax, ou un script bash/batch en CLI.
Deuxièmement, je vais ensuite développer un module qui a pour base ce dernier outil, et qui va gérer une navigation ajax facilement, en gérant les navigations sans javascript, comme dans cet article, et va utiliser les hash ‘#!’, pour les robots des moteurs de recherche.
J’ai actuellement bien avancé le projet, je refait un site en l’utilisant pour le tester et l’adapter à de nombreux cas d’utilisation.
Si cet outil intéresse quelqu’un, je vais le mettre en ligne d’ici deux ou trois mois (début 2013), avec une documentation.
Si vous souhaitez me contacter, doubjulien at hotmail dot fr
cordialement.