Beispiel für history.replaceState ()?

126

Kann jemand ein funktionierendes Beispiel für history.replaceState geben? Das sagt w3.org :

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

Aktualisiert den aktuellen Eintrag im Sitzungsverlauf, um die angegebenen Daten, den Titel und, falls angegeben und nicht null, die URL zu erhalten.

Aktualisieren:

Das funktioniert perfekt:

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

Die URL ändert sich, aber der Titel ändert sich nicht. Ist das ein Fehler oder fehlt mir etwas? Getestet auf dem neuesten Chrome.

Serjas
quelle
3
Ich drücke im Allgemeinen keine Add-On-Bibliotheken für JavaScript-Fragen, aber in diesem Fall mache ich eine Ausnahme. Die History.js- Bibliothek ist ein kleiner Shim, der viele bizarre Fehlverhalten in der History-API in modernen Browsern beseitigt. Es bietet sogar optionale Unterstützung für alte Versionen von IE.
Pointy
2
MDN hat eine ziemlich gute Beschreibung zum Manipulieren des Browserverlaufs
Sachleen
@Pointy history.js funktioniert großartig. Ich habe den Code in meiner Frage aktualisiert. Nein, mein Problem ist, dass ich nicht mit dem Browser-Zurück-Button zur vorherigen Seite zurückkehren kann
Serjas
3
Laut Mozilla wird der titleParameter nicht verwendet.
Rocket Hazmat
3
Die erste Antwort sollte wirklich nicht die akzeptierte Antwort sein, da die Frage nach einem replaceStateBeispiel fragt , und die akzeptierte Antwort ist in keiner Weise ein replaceStateBeispiel.
CorayThan

Antworten:

68

In der Tat ist dies ein Fehler, obwohl er seit 2 Jahren beabsichtigt ist. Das Problem liegt in einigen unklaren Spezifikationen und der Komplexität, wenn document.titleund vorwärts / rückwärts beteiligt sind.

Siehe Fehlerreferenz zu Webkit und Mozilla . Auch Opera bei der Einführung der History-API sagte, dass der title-Parameter nicht verwendet wurde und wahrscheinlich immer noch nicht.

Derzeit wird das zweite Argument von pushState und replaceState - der Titel des Verlaufseintrags - in der Opera-Implementierung nicht verwendet, kann aber eines Tages sein.

Mögliche Lösung

Die einzige Möglichkeit, die ich sehe, besteht darin, das Titelelement zu ändern und stattdessen pushState zu verwenden:

document.getElementsByTagName('title')[0].innerHTML = 'bar';
window.history.pushState( {} , 'bar', '/bar' );
Sev
quelle
Für jquery-Benutzer versuchen Sie $ ("title"). Html (_title);
Suraj Jain
3
Dies kann dazu führen, dass Benutzer auf die Schaltfläche "Zurück" doppelklicken müssen, je nachdem, wie Sie dies implementieren. Eine einfachere Lösung könnte darin bestehen, replaceState()den Dokumenttitel weiterhin manuell zu verwenden und einfach manuell document.title = "title"
festzulegen
38

Hier ist ein minimales, erfundenes Beispiel.

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

Es gibt noch mehr zu replaceState()tun , aber ich weiß nicht genau, was Sie damit machen wollen.

Trott
quelle
2
URL ändert sich, aber Titel ändert sich nicht .. getestet mit neuesten Chrome @trott
Serjas
6
@Serjas Der titleParameter in replaceState()wird nach meinem besten Wissen in allen Browsern ignoriert.
Trott
10

history.pushStateVerschiebt den aktuellen Seitenstatus auf den Verlaufsstapel und ändert die URL in der Adressleiste. Wenn Sie also zurückkehren, wird dieser Status (das Objekt, das Sie übergeben haben) an Sie zurückgegeben.

Derzeit ist das alles, was es tut. Alle anderen Seitenaktionen, z. B. das Anzeigen der neuen Seite oder das Ändern des Seitentitels, müssen von Ihnen ausgeführt werden.

Die von Ihnen verknüpfte W3C-Spezifikation ist nur ein Entwurf, und der Browser implementiert sie möglicherweise anders. Firefox beispielsweise ignoriert den titleParameter vollständig.

Hier ist ein einfaches Beispiel dafür pushState, das ich auf meiner Website verwende.

(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));
Rakete Hazmat
quelle
29
Warum erklärt die akzeptierte Antwort "pushState" anstelle von "replaceState"?
Giwrgos Tsopanoglou
1
@GiwrgosTsopanoglou: Ich habe dies vor einem Jahr beantwortet, daher bin ich mir nicht sicher, warum :-P Wie auch immer, replaceStateändert den aktuellen Seitenstatus. Hiermit können Sie das Statusobjekt und die URL des aktuellen Seitenstatus ändern .
Rocket Hazmat
2
Es war nur seltsam, dass ich nach Informationen über replaceState suchte und am Ende über pushState las: P
Giwrgos Tsopanoglou
6

schau dir das Beispiel an

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

und suchen location.hash;

Avalkab
quelle
2

Das zweite Argument Titel bedeutet nicht Titel der Seite - Es ist eher eine Definition / Information für den Status dieser Seite

Wir können den Titel jedoch weiterhin mit dem Ereignis onpopstate ändern und den Titelnamen nicht aus dem zweiten Argument, sondern als Attribut aus dem ersten als Objekt übergebenen Parameter übergeben

Referenz: http://spoiledmilk.com/blog/html5-changing-the-browser-url-without-refreshing-page/

Mahesh
quelle
2

Laut MDN History doc
wird klar gesagt, dass das zweite Argument für die Zukunft vorerst nicht verwendet wird. Sie haben Recht, dass das zweite Argument den Titel einer Webseite betrifft, aber derzeit von allen gängigen Browsern ignoriert wird.

Firefox ignoriert diesen Parameter derzeit, obwohl er möglicherweise in Zukunft verwendet wird. Das Übergeben der leeren Zeichenfolge sollte vor zukünftigen Änderungen an der Methode sicher sein. Alternativ können Sie einen kurzen Titel für den Status übergeben, in den Sie wechseln.

Munir Khakhi
quelle
Das zweite Argument bezieht sich nicht auf den Titel der Webseite. In dem von Ihnen verknüpften MDN-Dokument heißt es: "Übergeben Sie einen kurzen Titel für den Status, in den Sie wechseln." . Dies stimmt mit der Dokumentation der W3C- Verlaufsschnittstelle überein, die besagt, dass "die angegebenen Daten mit dem angegebenen Titel in den Sitzungsverlauf übertragen werden" . Die Daten in dieser Phrase sind die Zustandsdaten , daher bezieht sich der Titel wieder auf den Zustand (Daten).
Stephen P
1

Ich wollte unbedingt auf die Antwort von @ Sev antworten.

Sev hat recht, es gibt einen Fehler in der window.history.replaceState

Um dies zu beheben, schreiben Sie den Konstruktor einfach neu, um den Titel manuell festzulegen.

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);
}
DIE ERSTAUNLICHE
quelle
2
Tu das nicht. Das Überschreiben von Standardfunktionen ist wirklich ein schlechter Stil
René Roth
3
Was schlagen Sie noch vor, wenn Sie diesen Fehler beheben müssen?
Glenn Plas
@ GlennPlas öffnen Sie eine PR gegen das
React
0

Angenommen, https://www.mozilla.org/foo.html führt das folgende JavaScript aus:

const stateObj = { foo: 'bar' };

history.pushState(stateObj, '', 'bar.html');

Dies führt dazu, dass in der URL-Leiste https://www.mozilla.org/bar2.html angezeigt wird, der Browser jedoch nicht bar2.html lädt oder sogar überprüft, ob bar2.html vorhanden ist.

aschfahl
quelle