Können Sie die Hash-Navigation verwenden, ohne den Verlauf zu beeinflussen?

99

Ich fürchte, es könnte unmöglich sein, aber gibt es eine Möglichkeit, den Hashwert einer URL zu ändern, ohne einen Eintrag im Browserverlauf zu hinterlassen und ohne ihn neu zu laden ? Oder das Gleiche tun?

Was die Einzelheiten angeht, habe ich einige grundlegende Hash-Navigationen entwickelt, die wie folgt aussehen:

//hash nav -- works with js-tabs
var getHash = window.location.hash;
var hashPref = "tab-";
function useHash(newHash) {
    //set js-tab according to hash
    newHash = newHash.replace('#'+hashPref, '');
    $("#tabs li a[href='"+ newHash +"']").click();
}
function setHash(newHash) {
    //set hash according to js-tab
    window.location.hash = hashPref + newHash;

    //THIS IS WHERE I would like to REPLACE the location.hash
    //without a history entry

}
    // ... a lot of irrelavent tabs js and then....

    //make tabs work
    $("#tabs.js-tabs a").live("click", function() {
        var showMe = $(this).attr("href");
        $(showMe).show();
        setHash(showMe);
        return false;
    });
    //hash nav on ready .. if hash exists, execute
    if ( getHash ){
        useHash(getHash);
    }

Natürlich mit jQuery. Die Idee ist, dass in diesem speziellen Fall 1) das Zurückgehen des Benutzers bei jeder Tab-Änderung die Schaltfläche "Zurück" durch Aufstapeln unnötiger Referenzen effektiv "brechen" kann und 2) nicht beibehalten wird, auf welcher Registerkarte sie sich gerade befinden, wenn sie auf "Aktualisieren" klicken ein Ärger.


quelle
Warum möchten Sie den Hash ändern, wenn Sie den Verlauf nicht verfolgen möchten? : |
Ionuț Staicu
9
Da es beim Aktualisieren am besten ist, dem Benutzer die Registerkarte anzuzeigen, auf der er sich befand. Da er jedoch möglicherweise zwischen den Registerkarten hin- und herwechselt, wird sein Verlauf unnötig mit Einträgen überfüllt, wodurch die Schaltfläche "Zurück" tatsächlich weniger nützlich wird. Dies ist jedoch nur ein Beispiel - es kann jederzeit sein, dass Sie einen temporären Status speichern müssen, sich aber nicht auf Cookies verlassen oder die temporäre Datei des Benutzers damit füllen möchten. Wenn Sie aktualisieren, ist der js-Inhalt so, wie Sie ihn verlassen haben - Sie haben die Seite nicht verlassen und es handelt sich nicht um einen Sprungpunkt oder eine Pseudo-Seite, sodass der Verlaufseintrag nur die Standardnavigation beeinträchtigen kann.

Antworten:

94

location.replace("#hash_value_here");funktionierte gut für mich, bis ich feststellte, dass es unter IOS Chrome nicht funktioniert. In diesem Fall verwenden Sie:

history.replaceState(undefined, undefined, "#hash_value")

history.replaceState () funktioniert genau wie history.pushState (), außer dass replaceState () den aktuellen Verlaufseintrag ändert, anstatt einen neuen zu erstellen.

Denken Sie daran, den #oder den letzten Teil der URL beizubehalten.

Lucia
quelle
3
Der richtige Weg für moderne Browser. Beachten Sie jedoch die teilweise Unterstützung des Sitzungsverlaufs.
Matt
Ich bin verwirrt, wie man das benutzt. Soll ich noch window.location.hash = 'my-hash';gefolgt von verwenden history.replaceState(undefined, undefined, "#my-hash")?
Bram Vanroy
2
@BramVanroy Nein, letzteres ist ausreichend.
Lucia
2
Wenn Sie nicht verwenden: Zielselektoren ... dann sind Verlaufsfunktionen nutzlos, da dieser Teil der Spezifikation (CSS-Interaktion mit Verlaufsoperationen) derzeit nicht definiert zu sein scheint und der Stil beim Ersetzen des Verlaufs durch die meisten / alle Browser nicht neu berechnet wird.
Morphles
@Luxiyalu, wie unterscheidet history.replaceStatesich von location.replace?
Pacerier
99
location.replace("#hash_value_here"); 

Das Obige scheint das zu tun, wonach Sie suchen.

Matt
quelle
4
Das ist es. Und wenn Sie URI-Segmente haben, werden diese durch location.replace (window.location + "#hash") beibehalten.
Zetter
7
Wenn ich diese Methode unterstütze, viel sauberer, wünschte ich, sie wäre als die richtige Antwort markiert.
Joeellis
14
window.location.replace(('' + window.location).split('#')[0] + '#' + hash);um nur den Hash zu aktualisieren
Johnstorm
1
Ich teste es in Chrome 30 unter Windows 8. Wenn ich im Chrome-Verlauf unter meiner Test-URL "Mehr von dieser Site" auswähle, werden alle Hashes angezeigt, die mit dieser Methode hinzugefügt wurden.
Alex Vang
1
Beachten Sie, dass location.replace ('# hash_value_here') nur das Hash-Fragment und nicht den Pfad ändert, sodass kein Seitenladen ausgelöst wird. Außer wenn das Dokument ein Basis-Tag enthält: <base href ="http://example.com/" /> Wenn es ein Basis-Tag enthält Wenn Sie dann die Ersetzungsmethode nur mit einem führenden verwenden "#hash_value_here", sieht es tatsächlich so aus, als hätten Sie "location.replace" (" example.com/#hash_value_here" ) gesagt . Dies scheint offensichtlich zu sein, wenn Sie es hier lesen, ist aber ein Problem, wenn Sie sich auf einer Seite mit einem Pfadfragment befinden und nicht wissen, dass die Basis festgelegt ist.
Tyler Kasten
6

Bearbeiten: Es ist jetzt ein paar Jahre her und Browser haben sich weiterentwickelt.

@ Luxiyalus Antwort ist der richtige Weg

- Alte Antwort -

Ich denke auch, dass es unmöglich ist (zu diesem Zeitpunkt). Aber warum müssen Sie den Hash-Wert ändern, wenn Sie ihn nicht verwenden möchten?

Ich glaube, der Hauptgrund, warum wir den Hash-Wert als Programmierer verwenden, besteht darin, dass der Benutzer unsere Seiten mit einem Lesezeichen versehen oder einen Status im Browserverlauf speichern kann. Wenn Sie dies nicht tun möchten, speichern Sie einfach den Status in einer Variablen und arbeiten Sie von dort aus.

Ich denke, dass der Grund für die Verwendung eines Hashs darin besteht, mit einem Wert zu arbeiten, der außerhalb unserer Kontrolle liegt. Wenn Sie es nicht benötigen, bedeutet dies wahrscheinlich, dass Sie alles unter Ihrer Kontrolle haben. Speichern Sie den Status einfach in einer Variablen und arbeiten Sie damit. (Ich wiederhole mich gerne)

Ich hoffe das hilft dir weiter. Vielleicht gibt es eine einfachere Lösung für Ihr Problem.

UPDATE: Wie wäre es damit:

  1. Richten Sie einen ersten Hash ein und stellen Sie sicher, dass er im Browserverlauf gespeichert wird.
  2. Wenn eine neue Registerkarte ausgewählt wird window.history.back(1), wird der Verlauf von Ihrem ersten Init-Hash zurückgesetzt.
  3. Jetzt setzen Sie den neuen Hash, daher macht das Tabbing nur einen Eintrag im Verlauf.

Sie müssen wahrscheinlich einige Flags verwenden, um zu wissen, ob der aktuelle Eintrag durch Zurückgehen "gelöscht" werden kann, oder ob Sie nur den ersten Schritt überspringen. Und um sicherzustellen, dass Ihre Lademethode für den "Hash" nicht ausgeführt wird, wenn Sie das erzwingen history.back.

Guzart
quelle
Es ist sehr wahrscheinlich, dass mir etwas Grundlegendes fehlt (Erschöpfung ist eine nette Ausrede, ich werde damit weitermachen), aber sagen Sie, ich kann eine Variable festlegen, die ihren geänderten Wert beim erneuten Laden beibehält? Außerdem mit einem Keks? (Cookies scheinen irgendwie übertrieben.) Vielleicht war das nicht klar. Ich werde den Hash-Wert verwenden - insbesondere beim Neuladen. Danke für die Antwort!
Um meine Klarstellung zu verdeutlichen: Wenn der Benutzer auf reload klickt. Dafür ist der Hash da. Ich versuche immer noch, ein erneutes Laden bei normaler Verwendung zu vermeiden (Ändern / Klicken von Registerkarten).
Ok, Sie werden nach dem Neuladen einige Werte für Informationen verwenden. Nun, leider wird der Hash-Wert vom Verlauf eines Browsers ausgewählt. Tut mir leid, das zu sagen, aber meiner Erfahrung nach sind Cookies die beste Wahl. Wenn Sie etwas wollen, das der Browserverlauf nicht erkennt, aber nach dem Neuladen leider Cookies behalten soll. Wenn der Benutzer auf einen Link geklickt hat, können Sie den Link als Abfrage ( ?mystate=greatness) einrichten. Auch wenn es sich nicht um Ajax handeln muss, können Sie Informationen speichern, die das Javascript beim Initialisieren der Anforderung lesen kann.
Guzart
Ja, der Hash dient zum Speichern der Benutzerinformationen nach dem erneuten Laden. Das Problem für Sie ist jedoch, dass einige Browser diese Änderungen im Verlauf speichern. So funktionieren sie einfach ... :(
guzart
Ja, denke du hast recht. Ah, gut. (Würde gerne durch eine andere Methode oder so etwas als falsch erwiesen werden.)
-1

Sie können jederzeit einen Ereignis-Listener erstellen, um Klickereignisse im Hyperlink abzufangen, und in der Rückruffunktion e.preventDefault () eingeben, um zu verhindern, dass der Browser sie in den Verlauf einfügt.

Ayman Farhat
quelle