Dieser Status wird jedes Mal ersetzt, wenn sich Details ändern, damit sie im Verlauf gespeichert werden.
Es gibt drei Möglichkeiten, Stufe 2 zu verlassen:
speichern (AJAX senden)
stornieren
Zurück-Button
Die Zurück-Taste wird von der verwaltet popstate Hörer. Die Abbrechen-Schaltfläche schiebt Stufe 1, damit der Benutzer zu den Details zurückkehren kann, die er über die Zurück-Schaltfläche eingegeben hat. Diese beiden funktionieren gut.
Die Speichern-Schaltfläche sollte zu Stufe 1 zurückkehren und dem Benutzer nicht erlauben, zurück zur Detailseite zu navigieren (da sie bereits eingereicht haben). Grundsätzlich sollte der Verlaufsstapel die Länge = 1 haben.
Aber es scheint keine zu geben history.delete()oder history.merge(). Das Beste, was ich tun kann, ist a history.replaceState(stage1) was den Verlaufsstapel verlässt als: ["selectDate","selectDate"].
Wie werde ich eine Schicht los?
Bearbeiten:
Dachte an etwas anderes, aber es funktioniert auch nicht.
history.back(); //moves history to the correct position
location.href = "#foo"; // successfully removes ability to go 'forward',
// but also adds another layer to the history stack
Dies belässt den Verlaufsstapel als ["selectDate","selectDate#foo"].
Gibt es also alternativ eine Möglichkeit, die “Vorwärts” -Historie zu entfernen, ohne einen neuen Zustand zu erzwingen?
Mike B.
Sie sind vielleicht schon weitergezogen, aber … soweit ich weiß, gibt es keine Möglichkeit, einen Verlaufseintrag (oder Status) zu löschen.
Eine Option, die ich untersucht habe, besteht darin, den Verlauf selbst in JavaScript zu verwalten und die zu verwenden window.history Objekt als eine Art Träger.
Wenn die Seite zum ersten Mal geladen wird, erstellen Sie grundsätzlich Ihr benutzerdefiniertes Verlaufsobjekt (wir verwenden hier ein Array, verwenden jedoch das, was für Ihre Situation sinnvoll ist), und führen dann Ihre Initialisierung aus pushState. Ich würde Ihr benutzerdefiniertes Verlaufsobjekt als Zustandsobjekt übergeben, da es nützlich sein kann, wenn Sie auch mit Benutzern umgehen müssen, die von Ihrer App weg navigieren und später zurückkehren.
var myHistory = [];
function pageLoad() {
window.history.pushState(myHistory, "<name>", "<url>");
//Load page data.
}
Wenn Sie jetzt navigieren, fügen Sie Ihrem eigenen Verlaufsobjekt hinzu (oder nicht – der Verlauf liegt jetzt in Ihren Händen!) und verwenden replaceState um den Browser aus der Schleife zu halten.
Wenn der Benutzer rückwärts navigiert, erreicht er Ihren “Basis”-Zustand (Ihr Zustandsobjekt ist null) und Sie können die Navigation gemäß Ihrem benutzerdefinierten Verlaufsobjekt handhaben. Danach führen Sie einen weiteren pushState aus.
function on_popState() {
// Note that some browsers fire popState on initial load,
// so you should check your state object and handle things accordingly.
// (I did not do that in these examples!)
if (myHistory.length > 0) {
var pg = myHistory.pop();
window.history.pushState(myHistory, "<name>", "<url>");
//Load page data for "pg".
} else {
//No "history" - let them exit or keep them in the app.
}
}
Der Benutzer wird nie in der Lage sein, mit seinen Browser-Schaltflächen vorwärts zu navigieren, da er immer auf der neuesten Seite ist.
Aus der Perspektive des Browsers sind sie jedes Mal, wenn sie „zurück“ gehen, sofort wieder nach vorne gedrängt.
Aus der Perspektive des Benutzers können sie rückwärts durch die Seiten navigieren, aber nicht vorwärts (im Grunde simulieren sie das „Seitenstapel“-Modell des Smartphones).
Aus der Perspektive des Entwicklers haben Sie jetzt ein hohes Maß an Kontrolle darüber, wie der Benutzer durch Ihre Anwendung navigiert, während Sie ihm weiterhin die Verwendung der vertrauten Navigationsschaltflächen in seinem Browser ermöglichen. Sie können nach Belieben Elemente von überall in der Verlaufskette hinzufügen/entfernen. Wenn Sie Objekte in Ihrem Verlaufsarray verwenden, können Sie auch zusätzliche Informationen über die Seiten verfolgen (wie Feldinhalte und so weiter).
Wenn Sie eine vom Benutzer initiierte Navigation handhaben müssen (z. B. wenn der Benutzer die URL in einem Hash-basierten Navigationsschema ändert), verwenden Sie möglicherweise einen etwas anderen Ansatz wie …
var myHistory = [];
function pageLoad() {
// When the user first hits your page...
// Check the state to see what's going on.
if (window.history.state === null) {
// If the state is null, this is a NEW navigation,
// the user has navigated to your page directly (not using back/forward).
// First we establish a "back" page to catch backward navigation.
window.history.replaceState(
{ isBackPage: true },
"<back>",
"<back>"
);
// Then push an "app" page on top of that - this is where the user will sit.
// (As browsers vary, it might be safer to put this in a short setTimeout).
window.history.pushState(
{ isBackPage: false },
"<name>",
"<url>"
);
// We also need to start our history tracking.
myHistory.push("<whatever>");
return;
}
// If the state is NOT null, then the user is returning to our app via history navigation.
// (Load up the page based on the last entry of myHistory here)
if (window.history.state.isBackPage) {
// If the user came into our app via the back page,
// you can either push them forward one more step or just use pushState as above.
window.history.go(1);
// or window.history.pushState({ isBackPage: false }, "<name>", "<url>");
}
setTimeout(function() {
// Add our popstate event listener - doing it here should remove
// the issue of dealing with the browser firing it on initial page load.
window.addEventListener("popstate", on_popstate);
}, 100);
}
function on_popstate(e) {
if (e.state === null) {
// If there's no state at all, then the user must have navigated to a new hash.
// <Look at what they've done, maybe by reading the hash from the URL>
// <Change/load the new page and push it onto the myHistory stack>
// <Alternatively, ignore their navigation attempt by NOT loading anything new or adding to myHistory>
// Undo what they've done (as far as navigation) by kicking them backwards to the "app" page
window.history.go(-1);
// Optionally, you can throw another replaceState in here, e.g. if you want to change the visible URL.
// This would also prevent them from using the "forward" button to return to the new hash.
window.history.replaceState(
{ isBackPage: false },
"<new name>",
"<new url>"
);
} else {
if (e.state.isBackPage) {
// If there is state and it's the 'back' page...
if (myHistory.length > 0) {
// Pull/load the page from our custom history...
var pg = myHistory.pop();
// <load/render/whatever>
// And push them to our "app" page again
window.history.pushState(
{ isBackPage: false },
"<name>",
"<url>"
);
} else {
// No more history - let them exit or keep them in the app.
}
}
// Implied 'else' here - if there is state and it's NOT the 'back' page
// then we can ignore it since we're already on the page we want.
// (This is the case when we push the user back with window.history.go(-1) above)
}
}
Hey danke. Das ist etwas eleganter als das, was ich als Workaround verwendet habe.
– DanielST
24. März 2015 um 13:09 Uhr
Was tun, wenn ein Benutzer an dieses Verhalten gewöhnt ist, dann ein paar Mal navigiert, um einen Zustand aufzubauen, dann zu einer externen Website navigiert, dann zurück navigiert und ich annehme, dass der Verlauf der gesamten App-Navigation jetzt weg ist und die Zurück-Schaltfläche wird sein zuletzt auf dem Haufen.
– Billy Mond
17. Juni 2016 um 18:53 Uhr
Der von history.pushState gepushte Zustand ist verfügbar, wenn sie zurückkommen (auch wenn sie ihren Browser schließen oder aktualisieren). Einige Browser lösen beim Laden der Seite ein Popstate-Ereignis aus, andere nicht (z. B. Firefox). Aber Sie können history.state immer direkt lesen. Wenn Sie das Objekt history.state nicht verwenden, müssten Sie eine andere Methode verwenden, um Ihren Status beizubehalten (z. B. localStorage). history.state wird automatisch als Teil des Browserverlaufs beibehalten.
– Mike B.
17. Juni 2016 um 19:03 Uhr
So verschieben Sie die aktuelle Seite in myHistory, wie Sie sagten myHistory.push("page_im_in_now")? Nennen Sie mir bitte ein Beispiel
– Mr Perfekt
5. Dezember 2016 um 6:32 Uhr
Schöne Lösung! Ein kleines Problem könnte die Unfähigkeit sein, mehr als einen Schritt auf einmal zurückzugehen. Der Verlauf des Browsers zeigt immer nur zwei Einträge für eine solche Anwendung.
– Andrej
6. Mai 2017 um 22:17 Uhr
Es gibt keine Möglichkeit, die Vergangenheit zu löschen oder zu lesen.
Sie könnten versuchen, es zu umgehen, indem Sie die Geschichte in Ihrem eigenen Gedächtnis nachahmen und anrufen history.pushState jedes fenster popstate -Ereignis ausgegeben (was von der derzeit akzeptierten Antwort von Mike vorgeschlagen wird), aber es hat viele Nachteile, die zu einer noch schlechteren UX führen, als dass der Browserverlauf in Ihrer dynamischen Web-App überhaupt nicht unterstützt wird, weil:
Das Popstate-Ereignis kann auftreten, wenn der Benutzer ~ 2-3 Zustände in die Vergangenheit zurücksetzt
Das Popstate-Ereignis kann auftreten, wenn der Benutzer fortfährt
Selbst wenn Sie versuchen, es zu umgehen, indem Sie einen virtuellen Verlauf erstellen, ist es sehr wahrscheinlich, dass dies auch zu einer Situation führen kann, in der Sie leere Verlaufszustände haben (zu denen das Zurück-/Vorwärtsgehen nichts bewirkt) oder in der das Zurück-/Vorwärtsgehen einige überspringt Ihrer Geschichte Staaten total.
Ein weiteres Problem beim Versuch, vorwärts/rückwärts zu arbeiten, ist, dass der Titel im Verlauf gespeichert wird, wenn der Status gedrückt wird. Wenn ein Benutzer jetzt „Verlauf anzeigen“ verwendet oder mit der rechten Maustaste auf die Schaltfläche „Zurück“ klickt, kann der Benutzer zu einer Seite weitergeleitet werden, die er nicht erwartet hat, wenn Sie versuchen, etwas Intelligentes zu tun.
– Robokatze
6. Mai 2019 um 3:27 Uhr
Einige dieser Probleme sind ziemlich trivial zu lösen. Das Indizieren des Push-Zustands ist ein guter Anfang – so etwas wie a stateDepth Eigenschaft, die in der dekorierten inkrementiert wird pushStateneben a prevState. Wenn prevState.stateDepth === 4und Sie sind jetzt bei state.stateDepth === 2Sie haben eine gute Vorstellung davon, wie weit Sie zurück sind
– Nick Bull
10. Februar 2021 um 11:47 Uhr
Benutzerbild
Eine einfache Lösung:
var ismobilescreen = $(window).width() < 480;
var backhistory_pushed = false;
$('.editbtn').click( function()
{
// push to browser history, so back button will close the editor
// and not navigate away from site
if (ismobilescreen && !backhistory_pushed)
{
window.history.pushState('forward', null, window.location);
backhistory_pushed = true;
}
}
Dann:
if (window.history && window.history.pushState)
{
$(window).on('popstate', function()
{
if (ismobilescreen && backhistory_pushed && $('.editor').is(':visible'))
{
// hide editor window (we initiate a click on the cancel button)
$('.editor:visible .cancelbtn').click();
backhistory_pushed = false;
}
});
}
Ergebnisse in:
Der Benutzer öffnet den Editor DIV, der Verlaufsstatus wird gespeichert.
Der Benutzer klickt auf die Zurück-Schaltfläche, der Verlaufsstatus wird berücksichtigt.
Benutzer bleiben auf der Seite!
Statt zurück zu navigieren, wird der Editor DIV geschlossen.
Ein Problem: Wenn Sie eine „Abbrechen“-Schaltfläche auf Ihrem DIV verwenden und diese den Editor ausblendet, muss der Benutzer zweimal auf die Zurück-Schaltfläche des Mobiltelefons klicken, um zur vorherigen URL zurückzukehren.
Um dieses Problem zu lösen, können Sie anrufen window.history.back(); um den Verlaufseintrag selbst zu entfernen, was eigentlich löscht den Zustand wie gewünscht.
Alternativ könnten Sie eine URL in den Verlauf schieben, die einen Anker enthält, z #editor und dann in den Verlauf verschieben oder nicht, ob der Anker in der letzten URL vorhanden ist oder nicht.
14460100cookie-checkWie kann ich einen window.history-Zustand löschen?yes