Gestion History() et Ajax
La navigation Ajax dans un site internet, c'est merveilleux !... le seul véritable souci, c'est lorsque l'utilisateur joue avec les boutons de son navigateur ( < back(), F5 reload(), forward() > ) ... là, c'est la cata !... plus rien ne va, il se retrouve avec une page qu'il a visualisé il y a 1/2 heure, et est perdu !...
Bref, pas top pour stimuler l'appétit de son visiteur ...
Etant fan d'ajax, et devant réaliser impérativement un site en full Ajax pour un client, je me suis poser la question, comment faire !? après avoir regarder certaines lib qui font ça très bien, et avoir farfouillé de ci de là, je suis tombé sur une méthode qui fonctionne bien, et vous livre la class Navigation() !
Basée sur prototype, cette class vous permettra d'effectuer toutes vos requêtes Ajax, et stockera au passage les options de celles ci. Si par la suite, l'utilisateur reviens sur une page antérieur, la class Navigateur récupèrera les options précédemment utilisées pour les utiliser à nouveau lors de cette nouvelle requête (je pense notamment à la fonction onComplete de prototype)
Donc, premièrement, récupérer prototype.js récupérer le fichier NavigationAjax.js les stocker dans un dossier de votre hébergement et les lier à votre page !
Ce script s'adresse à des habitués de Javascript, je ne vais donc pas vous décrire toutes les opérations, mais simplement comment l'utiliser :
/**
* Navigation Class
* Management class using prototype to Ajax by generating a history navigation.
* @author nours312 code[at]nours312[dot]com
* @license free
*
*/
var Navigation = Class.create({
historyCurrent : 0,
historyRequest : false,
requests : [],
requestOnLoad : false,
curentRequest : "",
defParameters : {},
defaultSrc : null,
optionsOnload : null,
/**
* observe() recurrent function observe navigation and hash modifications
* if hash change, call this.onChange
*/
observe : function(){
window.setTimeout(this.observe.bind(this), 100);
var src = this.getCurrent();
if(src != this.curentRequest){
this.onChange(src);
}
this.requestOnLoad = false ;
},
/**
* getCurrent() get current hash
* @return {string}
*/
getCurrent : function(){
var hash = window.location.hash.substring(1);
return (hash =="") ? this.defaultSrc : hash ;
},
ajaxLoading : function(){
this.historyRequest = false;
},
onChange : function(url){
var re = this.lastUrl(url);
this.historyCurrent = re[0] ;
this.historyRequest = true;
this.curentRequest = url;
this.Request(url, re[1]);
},
addRequestAjax : function(url, options){
window.location.hash = url;
this.curentRequest = url;
this.historyCurrent ++ ;
this.requests[this.historyCurrent] = {src : url, obj : options};
this.requests.length = this.historyCurrent;
},
/**
* lastUrl(url)
* @param url {String} url required
* @return {Array}
*/
lastUrl : function(url){
var a = this.requests.findAll(function(v){
return (v.src == url);
});
var el = (a.length >= 1) ? [this.requests.indexOf(el), a[a.length-1].obj] : [0, {}] ;
return el ;
},
/**
* initialize([Ajax.options, [responder]])
* @param options {Object} default options used to request
* @param responder used to Ajax.Responders.register()
*/
initialize : function(){
if(arguments[0] !== undefined)
this.defParameters = arguments[0];
var href = window.location.href;
this.defaultSrc = href.substring(0, href.indexOf('#'));
this.requests[this.historyCurrent] = {src:this.defaultSrc, obj:{}};
this.Register({
onLoading : this.ajaxLoading.bind(this)
});
if(arguments[1] !== undefined)
this.Register(arguments[1]);
this.curentRequest = this.defaultSrc ;
this.observe() ;
},
/**
* Request(url, [options])
* @param url {string} to request
* @param options {Object} Ajax.options
*/
Request : function(url, options){
var op = options || {};
var p = (op.parameters === undefined) ? {} : op.parameters;
Object.extend(op, this.defParameters);
Object.extend(op.parameters, p);
if (!this.historyRequest)
this.addRequestAjax(url, options);
return new Ajax.Request(url, op);
},
/**
* Register(responder) call Ajax.Responders.register()
*/
Register : function(responder){
return Ajax.Responders.register(responder);
}
});
Une fois notre object Navigation Créé, il nous suffit de nous en servir.
// notre fonction callBack
var loadAjax = function(xhr){
alert("votre requete s'est bien é©ffectué©e");
}
//déclaration de notre object nav et déclaration des parametres par defaut
var nav = new Navigation({parameters :{ajax:1}, onComplete : loadAjax}, {
onCreate : Prototype.emptyFunction,
onLoading : Prototype.emptyFunction
});
//les options de cette nouvelle requete qui seront couplées à celles par deffaut
var options = {parameters : {maVar : 'c_ma_var'}, method:'get'};
//requete Ajax ...
nav.Request('maPage.html', options) ;
Voilà !... tant que vous utiliserez votre objet nav pour effectuer vos requêtes Ajax, vous empilerez dans votre historique les requêtes et continuerez à pouvoir utiliser votre navigateur pour les retours en arrière, ou le rechargement !...
Testé Sous IE7+ Safari 3+ FF3+ Chrome 1+ à voir sous IE6 ... mais j'en ai pas sous la main ;)
Amusez vous bien, et en attendant, n'hésitez pas à me poser vos questions !