(Hinweis: Gemäß Sharkys Feedback habe ich Code zum Erkennen von Backspaces eingefügt.)
Daher habe ich diese Fragen in SO häufig gesehen und bin kürzlich auf das Problem gestoßen, die Funktionalität von Zurück-Schaltflächen selbst zu steuern. Nach einigen Tagen der Suche nach der besten Lösung für meine Anwendung (Single-Page mit Hash-Navigation) habe ich ein einfaches, browserübergreifendes, bibliotheksloses System zur Erkennung der Zurück-Schaltfläche entwickelt.
Die meisten Leute empfehlen:
window.onhashchange = function() {
//blah blah blah
}
Diese Funktion wird jedoch auch aufgerufen, wenn ein Benutzer ein In-Page-Element verwendet, das den Standort-Hash ändert. Nicht die beste Benutzererfahrung, wenn Ihr Benutzer klickt und die Seite vorwärts oder rückwärts geht.
Um Ihnen einen allgemeinen Überblick über mein System zu geben, fülle ich ein Array mit vorherigen Hashes, während sich mein Benutzer durch die Benutzeroberfläche bewegt. Es sieht ungefähr so aus:
function updateHistory(curr) {
window.location.lasthash.push(window.location.hash);
window.location.hash = curr;
}
Ziemlich einfach. Ich mache dies, um die browserübergreifende Unterstützung sowie die Unterstützung älterer Browser sicherzustellen. Übergeben Sie einfach den neuen Hash an die Funktion, und er speichert ihn für Sie und ändert dann den Hash (der dann in den Verlauf des Browsers aufgenommen wird).
Ich verwende auch eine Schaltfläche zum Zurückseiten innerhalb der Seite, mit der der Benutzer mithilfe des lasthash
Arrays zwischen den Seiten verschoben wird. Es sieht aus wie das:
function goBack() {
window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
//blah blah blah
window.location.lasthash.pop();
}
Dadurch wird der Benutzer zurück zum letzten Hash verschoben und dieser letzte Hash aus dem Array entfernt (ich habe derzeit keine Schaltfläche zum Weiterleiten).
So. Wie erkenne ich, ob ein Benutzer meine In-Page-Zurück-Schaltfläche oder die Browser-Schaltfläche verwendet hat?
Zuerst habe ich mir das angeschaut window.onbeforeunload
, aber ohne Erfolg - das wird nur aufgerufen, wenn der Benutzer die Seiten wechseln will. Dies ist in einer Einzelseitenanwendung mit Hash-Navigation nicht der Fall.
Nach einigem Graben sah ich Empfehlungen für den Versuch, eine Flag-Variable zu setzen. Das Problem dabei ist in meinem Fall, dass ich versuchen würde, es festzulegen, aber da alles asynchron ist, würde es nicht immer rechtzeitig für die if-Anweisung in der Hash-Änderung festgelegt. .onMouseDown
wurde nicht immer mit einem Klick aufgerufen, und das Hinzufügen zu einem Onclick würde es niemals schnell genug auslösen.
Zu diesem Zeitpunkt begann ich, den Unterschied zwischen document
und zu untersuchen window
. Meine endgültige Lösung bestand darin, das Flag mit zu setzen document.onmouseover
und es mit zu deaktivieren document.onmouseleave
.
Während sich die Maus des Benutzers im Dokumentbereich befindet (lesen: die gerenderte Seite, jedoch ohne den Browser-Frame), wird mein Boolescher Wert auf gesetzt true
. Sobald die Maus den Dokumentbereich verlässt, wechselt der Boolesche Wert zu false
.
Auf diese Weise kann ich meine ändern window.onhashchange
zu:
window.onhashchange = function() {
if (window.innerDocClick) {
window.innerDocClick = false;
} else {
if (window.location.hash != '#undefined') {
goBack();
} else {
history.pushState("", document.title, window.location.pathname);
location.reload();
}
}
}
Sie werden den Scheck für notieren #undefined
. Dies liegt daran, dass wenn in meinem Array kein Verlauf verfügbar ist, dieser zurückgegeben wird undefined
. Ich benutze dies, um den Benutzer zu fragen, ob er mit einem window.onbeforeunload
Ereignis gehen möchte .
Kurz gesagt und für Personen, die nicht unbedingt eine In-Page-Zurück-Schaltfläche oder ein Array zum Speichern des Verlaufs verwenden:
document.onmouseover = function() {
//User's mouse is inside the page.
window.innerDocClick = true;
}
document.onmouseleave = function() {
//User's mouse has left the page.
window.innerDocClick = false;
}
window.onhashchange = function() {
if (window.innerDocClick) {
//Your own in-page mechanism triggered the hash change
} else {
//Browser back button was clicked
}
}
Und da hast du es. Eine einfache dreiteilige Methode zur Erkennung der Verwendung von Zurück-Schaltflächen im Vergleich zu In-Page-Elementen in Bezug auf die Hash-Navigation.
BEARBEITEN:
Um sicherzustellen, dass der Benutzer keine Rücktaste verwendet, um das Rückereignis auszulösen, können Sie auch Folgendes einschließen (Dank an @thetoolman für diese Frage ):
$(function(){
/*
* this swallows backspace keys on any non-input element.
* stops backspace -> back
*/
var rx = /INPUT|SELECT|TEXTAREA/i;
$(document).bind("keydown keypress", function(e){
if( e.which == 8 ){ // 8 == backspace
if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
e.preventDefault();
}
}
});
});