Verhindern Sie, dass eine Webseite mit JavaScript weg navigiert

128

Wie kann verhindert werden, dass eine Webseite mit JavaScript weg navigiert?

Software-Enthusiasten
quelle
Was bringt diese Seite dazu, weg zu navigieren?
Niyaz
9
Laut der Frage lässt JavaScript es weg navigieren ...
Shog9
@ Shog9 es könnte sein, dass das Schließen der Registerkarte es weg navigiert. Mein Zeigefinger tat das ...
Bob Stein

Antworten:

158

Mit onunloadkönnen Sie Nachrichten anzeigen, die Navigation wird jedoch nicht unterbrochen (da es zu spät ist). Die Verwendung onbeforeunloadunterbricht jedoch die Navigation:

window.onbeforeunload = function() {
  return "";
}

Hinweis: Eine leere Zeichenfolge wird zurückgegeben, da neuere Browser eine Meldung wie "Nicht gespeicherte Änderungen gehen verloren" anzeigen, die nicht überschrieben werden kann.

In älteren Browsern können Sie die Nachricht angeben, die in der Eingabeaufforderung angezeigt werden soll:

window.onbeforeunload = function() {
  return "Are you sure you want to navigate away?";
}
Jimmie R. Houts
quelle
11
Der Browser zeigt eine entsprechende Eingabeaufforderung an. Verwenden Sie einfachwindow.onbeforeunload = function() { return ""; }
KIM Taegyoon
Das reicht aber nicht. Was ist mit Steuerelementen im Formular? Sie lösen dies auch aus.
Fandango68
1
In modernen Browsern können Sie keine benutzerdefinierte Nachricht in der Eingabeaufforderung anzeigen, da diese von Phishern und dergleichen missbraucht wurde.
Flimm
Danke @Flimm, ich habe die Antwort aktualisiert, damit sie jetzt für aktuelle Browser korrekt ist.
Jimmie R. Houts
@FlimmIch möchte den Online-Status des Benutzers aktualisieren, wenn Online-Benutzer den Browser-Tab oder den Browser schließen. Ich habe den Code in der Lösung verwendet, aber er hat nicht funktioniert. Gibt es eine Lösung dafür?
Nasimba
23

Im Gegensatz zu anderen hier vorgestellten Methoden führt dieser Code nicht dazu, dass der Browser eine Warnung anzeigt, in der der Benutzer gefragt wird, ob er das Programm verlassen möchte. Stattdessen wird die ereignisreiche Natur des DOM ausgenutzt, um zur aktuellen Seite zurückzukehren (und damit die Navigation abzubrechen), bevor der Browser die Möglichkeit hat, sie aus dem Speicher zu entladen.

Da die Navigation direkt kurzgeschlossen wird, kann nicht verhindert werden, dass die Seite geschlossen wird. Es kann jedoch verwendet werden, um das Frame-Busting zu deaktivieren.

(function () {
    var location = window.document.location;

    var preventNavigation = function () {
        var originalHashValue = location.hash;

        window.setTimeout(function () {
            location.hash = 'preventNavigation' + ~~ (9999 * Math.random());
            location.hash = originalHashValue;
        }, 0);
    };

    window.addEventListener('beforeunload', preventNavigation, false);
    window.addEventListener('unload', preventNavigation, false);
})();

Haftungsausschluss: Sie sollten dies niemals tun. Wenn eine Seite einen Frame-Busting-Code enthält, respektieren Sie bitte die Wünsche des Autors.

anarchocurious
quelle
Wie zeige ich Modal, wenn der Benutzer den Browser schließen möchte (klicken Sie auf Schließen)? es wirklich?
15

Am Ende hatte ich diese etwas andere Version:

var dirty = false;
window.onbeforeunload = function() {
    return dirty ? "If you leave this page you will lose your unsaved changes." : null;
}

An anderer Stelle setze ich das Dirty-Flag auf true, wenn das Formular schmutzig wird (oder ich möchte auf andere Weise verhindern, dass ich weg navigiere). Auf diese Weise kann ich leicht steuern, ob der Benutzer die Eingabeaufforderung Navigation bestätigen erhält oder nicht.

Mit dem Text in der ausgewählten Antwort sehen Sie redundante Eingabeaufforderungen:

Geben Sie hier die Bildbeschreibung ein

Achtung
quelle
3
Wenn Dirty im IE falsch ist, wird eine Zeichenfolge 'null' angezeigt. Wickeln Sie es einfach in eine if-Anweisung. Siehe: stackoverflow.com/questions/11793996/…
Jacob van Lingen
Einverstanden mit @JacobvanLingen, dies wäre die beste Antwort hier und auf drei andere Fragen, wenn es undefinedstatt null enden würde. (1) es ist bedingt (2) es erwähnt "schmutzig" den häufigsten legitimen Grund, die Navigation zu behindern, und (3) es hat einen Screenshot.
Bob Stein
Würde dies in allen Browsern funktionieren, wenn es mit undefined statt null enden würde?
Gefahr
9

Das Äquivalent auf modernere und browserkompatiblere Weise unter Verwendung moderner addEventListener-APIs.

window.addEventListener('beforeunload', (event) => {
  // Cancel the event as stated by the standard.
  event.preventDefault();
  // Chrome requires returnValue to be set.
  event.returnValue = '';
});

Quelle: https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload

Paul Weber
quelle
1
Denken Sie daran, richtig groß zu schreibenevent.returnValue
Flimm
7

In Aymans Beispiel verhindern Sie durch die Rückgabe von false, dass das Browserfenster / die Registerkarte geschlossen wird.

window.onunload = function () {
  alert('You are trying to leave.');
  return false;
}
gabor
quelle
2
Es sei denn, der Browser ist Opera, der das Ereignis onunload überspringt, wenn die Registerkarte / das Fenster / das Programm geschlossen wird.
Powerlord
5

Das Äquivalent zur akzeptierten Antwort in jQuery 1.11:

$(window).on("beforeunload", function () {
    return "Please don't leave me!";
});

JSFiddle-Beispiel

Die Antwort von altCognito verwendete das unloadEreignis, das zu spät auftritt, als dass JavaScript die Navigation abbrechen könnte.

BoffinBrain
quelle
3

Verwenden Sie onunload .

Für jQuery funktioniert das meiner Meinung nach folgendermaßen:

$(window).unload(function() { 
  alert("Unloading"); 
  return falseIfYouWantToButBeCareful();
});
cgp
quelle
Wenn Sie false zurückgeben, wird das Entladen leider nicht abgebrochen - das unloadEreignis wird ausgelöst, wenn der Benutzer die Seite verlässt, im Gegensatz zu dem Ereignis, beforeunloaddas kurz zuvor ausgelöst wurde (und möglicherweise abgebrochen wird)
Jimbo,
@altCognito: Du hast mir mit falseIfYouWantToButBeCareful () eine gute Idee gegeben. Jetzt kann ich das von IE oder FF angegebene Standard-Popup vermeiden. Aber für Chrom funktioniert es nicht. Etwas nachgehen.
user367134
3

Diese vorgeschlagene Fehlermeldung kann die Fehlermeldung duplizieren, die der Browser bereits anzeigt. In Chrome werden die beiden ähnlichen Fehlermeldungen nacheinander im selben Fenster angezeigt.

In Chrome lautet der nach der benutzerdefinierten Nachricht angezeigte Text: "Möchten Sie diese Seite wirklich verlassen?". In Firefox wird unsere benutzerdefinierte Fehlermeldung überhaupt nicht angezeigt (der Dialog wird jedoch weiterhin angezeigt).

Eine geeignetere Fehlermeldung könnte sein:

window.onbeforeunload = function() {
    return "If you leave this page, you will lose any unsaved changes.";
}

Oder Stackoverflow-Stil: "Sie haben begonnen, einen Beitrag zu schreiben oder zu bearbeiten."

Curtis Yallop
quelle
2

Wenn Sie eine Browser-Zurück / Vorwärts-Schaltfläche abfangen und nicht weg navigieren möchten, können Sie Folgendes verwenden:

window.addEventListener('popstate', function() {
    if (window.location.origin !== 'http://example.com') {
        // Do something if not your domain
    } else if (window.location.href === 'http://example.com/sign-in/step-1') {
        window.history.go(2); // Skip the already-signed-in pages if the forward button was clicked
    } else if (window.location.href === 'http://example.com/sign-in/step-2') {
        window.history.go(-2); // Skip the already-signed-in pages if the back button was clicked
    } else {
        // Let it do its thing
    }
});

Andernfalls können Sie das Ereignis beforeunload verwenden , die Nachricht funktioniert jedoch möglicherweise browserübergreifend oder nicht und erfordert die Rückgabe von Informationen , die eine integrierte Eingabeaufforderung erzwingen.

ein bisschen weniger
quelle