ejemplo de history.replaceState ()?

127

¿Alguien puede dar un ejemplo de trabajo para history.replaceState? Esto es lo que dice w3.org :

history . replaceState(data, title [, url ] )

Actualiza la entrada actual en el historial de la sesión para tener los datos, el título y, si se proporcionan y no son nulos, la URL.

Actualizar:

Esto funciona perfectamente:

history.replaceState( {} , 'foo', '/foo' );

La URL está cambiando, pero el título no está cambiando. ¿Es un error o me falta algo? Probado en el último Chrome.

Serjas
fuente
3
En general, no envío bibliotecas de complementos para preguntas de JavaScript, pero en este caso haré una excepción. La biblioteca History.js es una pequeña cuña que limpia muchos comportamientos extraños en la API de historial en los navegadores modernos. Incluso proporciona soporte opcional para versiones antiguas de IE.
Puntiagudo
2
MDN tiene una muy buena redacción sobre Manipulación del historial del navegador
sachleen
@Pointy history.js funciona muy bien. He actualizado el código en mi pregunta. No, mi problema es que no puedo volver a la página anterior con el botón de retroceso del navegador
Serjas
3
Según Mozilla , el titleparámetro no se usa realmente.
Rocket Hazmat el
3
La primera respuesta realmente no debería ser la respuesta aceptada, dado que la pregunta pide un replaceStateejemplo, y la respuesta aceptada no es en modo alguno un replaceStateejemplo.
CorayThan

Respuestas:

68

De hecho, esto es un error, aunque intencional desde hace 2 años. El problema radica en algunas especificaciones poco claras y la complejidad cuando document.titleestán involucrados y viceversa.

Consulte la referencia de errores en Webkit y Mozilla . También Opera, en la introducción de History API, dijo que no estaba usando el parámetro de título y probablemente todavía no lo hace.

Actualmente, el segundo argumento de pushState y replaceState, el título de la entrada del historial, no se usa en la implementación de Opera, pero puede ser un día.

Solucion potencial

La única forma en que veo es alterar el elemento del título y usar pushState en su lugar:

document.getElementsByTagName('title')[0].innerHTML = 'bar';
window.history.pushState( {} , 'bar', '/bar' );
Sev
fuente
Para usuarios de jquery ... intente $ ("título"). Html (_title);
suraj jain
3
esto podría ocasionar que los usuarios necesiten "hacer doble clic" en el botón Atrás dependiendo de cómo implementen esto. Una solución más simple podría ser la de seguir usando replaceState()y simplemente establecer el título del documento manualmentedocument.title = "title"
newshorts
38

Aquí hay un ejemplo mínimo y artificial.

console.log( window.location.href );  // whatever your current location href is
window.history.replaceState( {} , 'foo', '/foo' );
console.log( window.location.href );  // oh, hey, it replaced the path with /foo

Hay más, replaceState()pero no sé qué es exactamente lo que quieres hacer con él.

Trott
fuente
2
url está cambiando, pero el título no está cambiando ... probado con el último Chrome @trott
Serjas
66
@Serjas El titleparámetro en replaceState()es, que yo sepa, ignorado en todos los navegadores.
Trott
10

history.pushStateempuja el estado actual de la página a la pila del historial y cambia la URL en la barra de direcciones. Entonces, cuando regresas, ese estado (el objeto que pasaste) te es devuelto.

Actualmente, eso es todo lo que hace. Usted debe realizar cualquier otra acción de página, como mostrar la nueva página o cambiar el título de la página.

La especificación W3C que vincula es solo un borrador, y el navegador puede implementarla de manera diferente. Firefox , por ejemplo, ignora el titleparámetro por completo.

Aquí hay un ejemplo simple de lo pushStateque uso en mi sitio web.

(function($){
    // Use AJAX to load the page, and change the title
    function loadPage(sel, p){
        $(sel).load(p + ' #content', function(){
            document.title = $('#pageData').data('title');
        });
    }

    // When a link is clicked, use AJAX to load that page
    // but use pushState to change the URL bar
    $(document).on('click', 'a', function(e){
        e.preventDefault();
        history.pushState({page: this.href}, '', this.href);
        loadPage('#frontPage', this.href);
    });

    // This event is triggered when you visit a page in the history
    // like when yu push the "back" button
    $(window).on('popstate', function(e){
        loadPage('#frontPage', location.pathname);
        console.log(e.originalEvent.state);
    });
}(jQuery));
Cohete Hazmat
fuente
29
¿Por qué la respuesta aceptada explica "pushState" en lugar de "replaceState"?
Giwrgos Tsopanoglou
1
@GiwrgosTsopanoglou: Respondí esto hace un año, así que no estoy seguro de por qué :-P De todos modos, replaceStatecambia el estado actual de la página. Le permite cambiar el objeto de estado y la URL del estado actual de la página.
Rocket Hazmat
2
Era extraño que buscara información sobre replaceState y terminé leyendo sobre pushState: P
Giwrgos Tsopanoglou
6

mira el ejemplo

window.history.replaceState({
    foo: 'bar'
}, 'Nice URL Title', '/nice_url');

window.onpopstate = function (e) {
    if (typeof e.state == "object" && e.state.foo == "bar") {
        alert("Blah blah blah");
    }
};

window.history.go(-1);

y buscar location.hash;

avalkab
fuente
2

Según MDN History doc.
Se dice claramente que el segundo argumento es para el futuro, no por el momento. Tienes razón, el segundo argumento es tratar con el título de la página web, pero actualmente es ignorado por todos los principales navegadores.

Firefox actualmente ignora este parámetro, aunque puede usarlo en el futuro. Pasar la cadena vacía aquí debería estar a salvo de futuros cambios en el método. Alternativamente, puede pasar un título corto para el estado al que se está mudando.

Munir Khakhi
fuente
El segundo argumento no se refiere al título de la página web: el documento de MDN que vinculó dice "pasar un título corto para el estado al que se está mudando". . Esto concuerda con la documentación de la interfaz del historial del W3C que dice "Inserta los datos dados en el historial de la sesión, con el título dado" . Los datos en esa frase son los datos del estado , por lo que nuevamente el título se refiere al estado (datos).
Stephen P
1

Realmente quería responder a la respuesta de @ Sev.

Sev tiene razón, hay un error dentro del window.history.replaceState

Para solucionar esto, simplemente reescriba el constructor para configurar el título manualmente.

var replaceState_tmp = window.history.replaceState.constructor;
window.history.replaceState.constructor = function(obj, title, url){
    var title_ = document.getElementsByTagName('title')[0];
    if(title_ != undefined){
        title_.innerHTML = title;
    }else{
        var title__ = document.createElement('title');
        title__.innerHTML = title;
        var head_ = document.getElementsByTagName('head')[0];
        if(head_ != undefined){
            head_.appendChild(title__);
        }else{
            var head__ = document.createElement('head');
            document.documentElement.appendChild(head__);
            head__.appendChild(title__);
        }
    }
    replaceState_tmp(obj,title, url);
}
LO ASOMBROSO
fuente
2
No hagas eso. Sobrescribir las funciones predeterminadas es un estilo realmente malo
René Roth
3
¿Qué más sugieres cuando necesitas corregir este error?
Glenn Plas
@GlennPlas abre un RP contra el repositorio de reacción :)
zero_cool