replacestate - Historial del navegador ajax de jquery con window.history.pushState y fallback
window.history clear (3)
Quiero implementar un historial de navegación usando jQuery y AJAX de forma cruzada. Mi enfoque es usar window.history.pushState
y recurrir a un hash url /#!/url
en los navegadores que no son compatibles con window.history.pushState
.
Por ejemplo:
<a href="/home">home</a>
<a href="/about">about</a>
<a href="/contact">contact</a>
En los navegadores compatibles con window.history.pushState
, al hacer clic en uno de estos enlaces, se debe cambiar la dirección sin actualizar la página a http://domain.com/home , http://domain.com/about , etc. Cuando el navegador no es compatible. window.history.pushState
, debe usar un identificador de fragmento, es decir: http://domain.com/#!/home , http://domain.com/#!/about .
Actualización: En base a los comentarios aquí, he implementado Ajax SEO ( git ) que usa jQuery Address para la API de historial de HTML5 con la antigua opción de reemplazo del navegador a /#!/url
.
Algo que he estado usando con las URL hash de respaldo:
History = History || {};
History.pathname = null;
History.previousHash = null;
History.hashCheckInterval = -1;
History.stack = [];
History.initialize = function () {
if (History.supportsHistoryPushState()) {
History.pathname = document.location.pathname;
$(window).bind("popstate", History.onHistoryChanged);
} else {
History.hashCheckInterval = setInterval(History.onCheckHash, 200);
}
};
History.supportsHistoryPushState = function () {
return ("pushState" in window.history) && window.history.pushState !== null;
};
History.onCheckHash = function () {
if (document.location.hash !== History.previousHash) {
History.navigateToPath(document.location.hash.slice(1));
History.previousHash = document.location.hash;
}
};
History.pushState = function (url) {
if (History.supportsHistoryPushState()) {
window.history.pushState("", "", url);
} else {
History.previousHash = url;
document.location.hash = url;
}
History.stack.push(url);
};
History.onHistoryChanged = function (event) {
if (History.supportsHistoryPushState()) {
if(History.pathname != document.location.pathname){
History.pathname = null;
History.navigateToPath(document.location.pathname);
}
}
};
History.navigateToPath = function(pathname) {
History.pushState(pathname);
// DO SOME HANDLING OF YOUR PATH HERE
};
Podrías vincular tus eventos de clic a esto con:
$(function(){
$("a").click(function(){
var href = $(this).attr(''href'');
History.navigateToPath( href )
return false;
});
});
Si necesita más explicaciones sobre este ejemplo, estaré encantado de escucharlo.
EDITAR
Por favor mira mi otra respuesta.
Ha pasado un tiempo desde mi respuesta original y ahora sugeriría usar Backbone .
Una implementación podría ser:
// First setup a router which will be the responder for URL changes:
var AppRouter = Backbone.Router.extend({
routes: {
"*path": "load_content"
},
load_content: function(path){
$(''#content'').load(''/'' + path);
}
});
var appRouter = new AppRouter;
// Then initialize Backbone''s history
Backbone.history.start({pushState: true});
Extracto de la documentación:
Para indicar que desea utilizar el soporte de HTML5
pushState
en su aplicación, useBackbone.history.start({pushState: true})
. Si desea utilizarpushState
, pero si los navegadores no lo admiten de forma nativa, utiliza actualizaciones de página completa en su lugar, puede agregar{hashChange: false}
a las opciones.
Y ahora cada vez que se llama Backbone.history.navigate
, el AppRouter
realizará una carga AJAX de la ruta dentro del div #content
.
Para manejar todos los enlaces con AJAX, puede usar lo siguiente:
$("a").on(''click'', function(event){
event.preventDefault();
Backbone.history.navigate( event.currentTarget.pathname, {trigger: true} )
});
Tome nota del {trigger: true}
que hace que se llame al controlador en el enrutador (de lo contrario, solo a partir de los cambios de URL)
Violín con código de ejemplo: http://jsfiddle.net/koenpunt/pkAz7/1/
// Assuming the path is retreived and stored in a variable ''path''
if (typeof(window.history.pushState) == ''function'') {
window.history.pushState(null, path, path);
} else {
window.location.hash = ''#!'' + path;
}