Wie kann ich verhindern, dass eine Seite in JS entladen wird (weg navigiert)?

70

Weiß jemand, wie man verhindert, dass eine Seite neu geladen oder weg navigiert wird?

jQuery (Funktion ($) {

    / * global beim Entladen * /
    Warnung = wahr;

    if (Warnung) {
        $ (Fenster) .bind ("entladen", function () { 
            if (bestätigen ("Möchten Sie diese Seite verlassen") == true) {
                // Sie drückten OK
                alert ('ok');
            } else {
                // Sie drückten Abbrechen
                alert ('Abbrechen');
                falsch zurückgeben;
            }}
        });
    }}
});

Ich arbeite gerade an einer E-Commerce-Website. Auf der Seite, auf der Ihre zukünftigen Bestellungen angezeigt werden, können Sie die Anzahl der bestellten Artikel mithilfe der Schaltflächen +/- ändern. Wenn Sie die Mengen auf diese Weise ändern, ändert sich die Bestellung selbst nicht. Sie müssen auf Bestätigen klicken und daher eine positive Aktion ausführen, um die Bestellung zu ändern.

Wenn sie jedoch die Mengen geändert haben und von der Seite weg navigieren, möchte ich sie warnen, dass sie dies tun, falls dies ein Unfall ist, da die geänderten Mengen verloren gehen, wenn sie weg navigieren oder die Seite aktualisieren.

Im obigen Code verwende ich eine globale Variable, die standardmäßig falsch ist (dies gilt nur für Tests). Wenn eine Menge geändert wird, aktualisiere ich diese Variable auf wahr und wenn sie die Änderungen bestätigt, setze ich sie auf falsch .

Wenn die Warnung wahr ist und die Seite entladen wird, biete ich ihnen ein Bestätigungsfeld an. Wenn sie Nein sagen, möchten sie auf dieser Seite bleiben, muss ich das Entladen verhindern. return false funktioniert nicht, lässt den Benutzer dennoch weg navigieren (die Warnungen dienen nur zum Debuggen)

Irgendwelche Ideen?

Natalie Downe
quelle
Siehe auch
AlikElzin-kilaka

Antworten:

85

onbeforeunloadist derjenige, den du willst; Ihre Funktion "sollte der returnValue-Eigenschaft des Event-Objekts einen Zeichenfolgenwert zuweisen und dieselbe Zeichenfolge zurückgeben" . Überprüfen Sie die Dokumente von Microsoft und Mozilla auf Details.

Die von Ihnen zurückgegebene Zeichenfolge wird vom Browser verwendet, um dem Benutzer ein benutzerdefiniertes Bestätigungsfeld anzuzeigen, mit dem er sich weigern kann, dort zu bleiben, wenn er dies wünscht. Dies muss auf diese Weise geschehen, um zu verhindern, dass böswillige Skripte einen Denial-of-Browser-Angriff verursachen.

NickFitz
quelle
3
Es sollte beachtet werden, dass, wenn Sie jQuery verwenden, um das Ereignis zu binden, Sie an binden sollten beforeunload(lassen Sie den onTeil der Zeichenfolge
weg
Dies funktioniert in modernen Browsern nicht mehr. Sie können keine benutzerdefinierte Nachricht in das angezeigte Feld einfügen. (Sicherheitsgründe offensichtlich)
mlwacosmos
70

Dieser Code warnt gemäß Natalies Vorschlag, deaktiviert jedoch die Warnung, wenn ein Formular auf der Seite gesendet wurde. Verwendet JQuery.

var warning = true;
window.onbeforeunload = function() { 
  if (warning) {
    return "You have made changes on this page that you have not yet confirmed. If you navigate away from this page you will lose your unsaved changes";
  }
}

$('form').submit(function() {
   window.onbeforeunload = null;
});
Handwerker
quelle
9
Warum das Downvote? Ich antwortete und fügte dem Thema hinzu. Die Warnvariable dient zur Veranschaulichung eines Proof of Concept. Schalten Sie es aus oder entfernen Sie es. Ich bin sicher, dass die meisten Benutzer den Code nicht wörtlich von dieser Site kopieren und so verwenden, wie er ist.
Crafter
7
Ich vermute, die Abwertung liegt daran, dass Sie die Warnvariable festlegen und sie dann nicht in Ihrer Übermittlungsfunktion verwenden, z. B. nur warning=falseanstelle vonwindow.onbeforeunload = null
Bob Vale
2
Die Warnung wird im Falle einer Übermittlungsaktion nicht benötigt ... nur wenn der Benutzer versucht, die Seite OHNE Übermittlung zu verlassen.
Jcorry
20

Sie möchten das Ereignis onbeforeunload verwenden .

scunliffe
quelle
@scunliffe - in jQuery bedeutet "entladen" "onbeforeunload", das ist, was sie tut.
Karim79
17
@ Karim79: Nein, tut es nicht. In jQuery gibt es nichts, was an die Funktion beforeunload gebunden wäre. "entladen" bindet an das Ereignis "entladen". Suche die Quelle, wenn du mir nicht glaubst
;-)
5
window.onbeforeunload = confirmExit;
function confirmExit()
{
    return "You have attempted to leave this page.  If you have made any changes to the fields without clicking the Save button, your changes will be lost.  Are you sure you want to exit this page?";
}
VIKRANT SHARMA
quelle
4
window.onbeforeunload = function() { 
  if (warning) {
    return `You have made changes on this page that you have not yet confirmed. 
    If you navigate away from this page you will lose your unsaved changes`;
  }
}

Wird in Chrom, Safari und Oper nicht unterstützt

Justin Liu
quelle
4
Wird in Chrome nicht unterstützt? Ich bin mir ziemlich sicher, dass SO mir einen solchen Dialog präsentiert, wenn ich etwas in den Editor eingegeben habe (ich verwende Chrome 4.0.206.0 unter Linux)
Joachim Sauer
Sie benötigen eine mehrzeilige Zeichenfolge.
Justin Liu
0

Wie in diesem Kommentar erwähnt, ist nichts in jQuery an das beforeunloadEreignis gebunden .

@ Karim79: Nein, tut es nicht. In jQuery gibt es nichts, was an die Funktion beforeunload gebunden wäre. "entladen" bindet an das Ereignis "entladen". Suche die Quelle, wenn du mir nicht glaubst ;-) - NickFitz

Sie müssen also reines Javascript verwenden, um eine Funktion an das beforeunloadEreignis zu binden .

var warning = true;
$("form").submit(function() {
  warning = false;
});
$('#exit').click(function() {
  window.location.replace('https://stacksnippets.net/js')
});
window.onbeforeunload = function() {
  if(warning) {
    return true;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<form>
<input type="submit">
</form>

Justin Liu
quelle
-4

Versuchen Sie es mit, e.preventDefault()anstatt false zurückzugeben. 'e' wäre das erste Argument für Ihren Rückruf zum Entladen .

NSSec
quelle
@MathieuK - Ich habe abgestimmt, weil ich denke, dass Sie Recht haben, aber Sie sollten wahrscheinlich entweder 1) ein Beispiel einfügen oder 2) den Code in der Frage ändern, um Ihren Vorschlag aufzunehmen, bevor jemand anderes kommt und das tut;)
karim79
14
verhindern, dass Default keine Auswirkungen auf das Entladeereignis hat - ein Skript kann das Entladen nicht abbrechen, da dies einer böswilligen Site ermöglichen würde, das Browserfenster zu entführen.
NickFitz
Preventdefault ist nicht auf dem Entladeereignis implementiert
Jens Meinecke