esempio history.replaceState ()?


127

Qualcuno può dare un esempio funzionante per history.replaceState? Questo è ciò che dice w3.org :

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

Aggiorna la voce corrente nella cronologia della sessione per avere dati, titolo e, se forniti e non null, URL forniti.

Aggiornare:

Funziona perfettamente:

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

L'URL sta cambiando, ma il titolo non sta cambiando. È un bug o mi sto perdendo qualcosa? Testato sull'ultimo Chrome.


3
In genere non invio librerie di componenti aggiuntivi per domande JavaScript, ma in questo caso farò un'eccezione. La libreria History.js è un piccolo spessore che elimina molti bizzarri comportamenti errati nell'API History attraverso i browser moderni. Fornisce anche supporto opzionale per le vecchie versioni di IE.
Punta l'

2
MDN ha scritto un articolo abbastanza buono su Manipolazione della cronologia del browser
sachleen

@Pointy history.js funziona alla grande. Ho aggiornato il codice nella mia domanda. No il mio problema è che non posso tornare alla pagina precedente con il pulsante Indietro del browser
Serjas,

3
Secondo Mozilla , il titleparametro non è effettivamente utilizzato.
Rocket Hazmat,

3
La prima risposta in realtà non dovrebbe essere la risposta accettata, dato che la domanda richiede un replaceStateesempio e la risposta accettata non è in alcun modo un replaceStateesempio.
Coray,

Risposte:


68

In effetti questo è un bug, sebbene intenzionale da 2 anni ormai. Il problema risiede con alcune specifiche poco chiare e la complessità quando document.titlesono coinvolti e il back / forward.

Vedi riferimento ai bug su Webkit e Mozilla . Anche Opera sull'introduzione dell'API History ha affermato di non utilizzare il parametro title e probabilmente non lo fa ancora.

Attualmente il secondo argomento di pushState e replaceState - il titolo della cronologia - non viene utilizzato nell'implementazione di Opera, ma potrebbe essere un giorno.

Soluzione potenziale

L'unico modo in cui vedo è di modificare l'elemento del titolo e utilizzare invece PushState:

document.getElementsByTagName('title')[0].innerHTML = 'bar';
window.history.pushState( {} , 'bar', '/bar' );

Per gli utenti jquery .. prova $ ("titolo"). Html (_title);
suraj jain,

3
ciò potrebbe comportare la necessità per gli utenti di "fare doppio clic" sul pulsante Indietro in base alla modalità di implementazione. Una soluzione più semplice potrebbe essere quella di continuare a utilizzare replaceState()e semplicemente impostare manualmente il titolo del documentodocument.title = "title"
newshorts

38

Ecco un esempio minimale, inventato.

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

C'è altro da fare, replaceState()ma non so che cosa esattamente si voglia farci.


2
l'URL sta cambiando, ma il titolo non sta cambiando .. testato con l'ultimo Chrome @trott
Serjas,

6
@Serjas Il titleparametro in replaceState()è, per quanto ne sappia , ignorato in tutti i browser.
Trott,

10

history.pushStateinserisce lo stato della pagina corrente nello stack della cronologia e modifica l'URL nella barra degli indirizzi. Quindi, quando torni indietro, quello stato (l'oggetto che hai passato) ti viene restituito.

Attualmente, è tutto ciò che fa. Qualsiasi altra azione sulla pagina, come la visualizzazione della nuova pagina o la modifica del titolo della pagina, deve essere eseguita dall'utente.

Le specifiche W3C che colleghi sono solo una bozza e il browser potrebbe implementarle in modo diverso. Firefox , ad esempio, ignora titlecompletamente il parametro.

Ecco un semplice esempio di pushStatequello che uso sul mio sito 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));

29
Perché la risposta accettata spiega "pushState" invece di "replaceState"?
Giwrgos Tsopanoglou,

1
@GiwrgosTsopanoglou: ho risposto a questo un anno fa, quindi non sono sicuro del perché :-P Ad ogni modo, replaceStatecambia lo stato della pagina corrente. Ti consente di modificare l'oggetto stato e l'URL dello stato della pagina corrente .
Rocket Hazmat,

2
Era strano che stavo cercando informazioni su ReplaceState e ho finito per leggere di pushState: P
Giwrgos Tsopanoglou,

6

guarda l'esempio

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);

e cerca location.hash;



2

Secondo il documento di storia della MDN
Si dice chiaramente che il secondo argomento è per il futuro usato non per ora. Hai ragione sul fatto che il secondo argomento riguarda il titolo della pagina web ma attualmente è ignorato da tutti i principali browser.

Firefox attualmente ignora questo parametro, sebbene possa utilizzarlo in futuro. Passare la stringa vuota qui dovrebbe essere sicuro contro future modifiche al metodo. In alternativa, potresti passare un breve titolo per lo stato in cui ti stai trasferendo.


Il secondo argomento non si riferisce al titolo della pagina Web - il documento MDN che hai collegato dice "passa un breve titolo per lo stato in cui ti stai spostando". . Ciò concorda con la documentazione dell'interfaccia della cronologia del W3C che dice "Invia i dati dati nella cronologia della sessione, con il titolo dato" . I dati in quella frase sono i dati di stato , quindi il titolo si riferisce allo stato (dati).
Stephen P,

1

Volevo davvero rispondere alla risposta di @ Sev.

Sev ha ragione, c'è un bug all'interno di window.history.replaceState

Per risolvere questo problema, basta riscrivere il costruttore per impostare manualmente il titolo.

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);
}

2
Non farlo. Sovrascrivere le funzioni predefinite è in realtà uno stile pessimo
René Roth

3
cos'altro suggerisci quando hai bisogno di correggere questo bug?
Glenn Plas,

@GlennPlas apre un PR contro il pronti contro termine di reazione :)
zero_cool

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.