So zeigen Sie an: "Möchten Sie wirklich von dieser Seite weg navigieren?" Wann wurden Änderungen vorgenommen?

267

Wenn Sie hier im Stackoverflow Änderungen vornehmen und versuchen, von der Seite weg zu navigieren, wird eine Javascript-Bestätigungsschaltfläche angezeigt, in der Sie gefragt werden: "Möchten Sie wirklich von dieser Seite weg navigieren?" blee bla bla ...

Hat jemand dies bereits implementiert? Wie kann ich nachverfolgen, ob Änderungen festgeschrieben wurden? Ich glaube, ich könnte das selbst tun, ich versuche, die guten Praktiken von Ihnen, den Experten, zu lernen.

Ich habe Folgendes versucht, funktioniert aber immer noch nicht:

<html>
<body>
    <p>Close the page to trigger the onunload event.</p>
    <script type="text/javascript">
        var changes = false;        
        window.onbeforeunload = function() {
            if (changes)
            {
                var message = "Are you sure you want to navigate away from this page?\n\nYou have started writing or editing a post.\n\nPress OK to continue or Cancel to stay on the current page.";
                if (confirm(message)) return true;
                else return false;
            }
        }
    </script>

    <input type='text' onchange='changes=true;'> </input>
</body>
</html>

Kann jemand ein Beispiel posten?

Shimmy Weitzhandler
quelle
3
Damit Ihr Beispiel funktioniert, ändern Sie die Funktion in: myFunction () {window.onbeforeunload = "message"; } Ändern Sie dann die Eingabe: <input type = 'text' onchange = 'myFunction ();'> </ input>
Keith
Siehe auch
AlikElzin-kilaka

Antworten:

367

Update (2017)

Moderne Browser betrachten das Anzeigen einer benutzerdefinierten Nachricht jetzt als Sicherheitsrisiko und wurden daher von allen entfernt . Browser zeigen jetzt nur allgemeine Nachrichten an. Da wir uns nicht mehr um das Einstellen der Nachricht kümmern müssen, ist dies so einfach wie:

// Enable navigation prompt
window.onbeforeunload = function() {
    return true;
};
// Remove navigation prompt
window.onbeforeunload = null;

Lesen Sie weiter unten, um Unterstützung für ältere Browser zu erhalten.

Update (2013)

Die ursprüngliche Antwort ist für IE6-8 und FX1-3.5 geeignet (auf die wir bereits 2009 abzielten, als sie geschrieben wurde), ist aber jetzt ziemlich veraltet und funktioniert in den meisten aktuellen Browsern nicht mehr - ich bin gegangen es unten als Referenz.

Das window.onbeforeunloadwird nicht von allen Browsern konsistent behandelt. Es sollte eine Funktionsreferenz und keine Zeichenfolge sein (wie in der ursprünglichen Antwort angegeben), aber das funktioniert in älteren Browsern, da die Prüfung für die meisten von ihnen zu sein scheint, ob etwas zugewiesen ist onbeforeunload(einschließlich einer Funktion, die zurückgibt null).

Sie haben window.onbeforeunloadeine Funktionsreferenz festgelegt, aber in älteren Browsern müssen Sie returnValuedas Ereignis festlegen, anstatt nur eine Zeichenfolge zurückzugeben:

var confirmOnPageExit = function (e) 
{
    // If we haven't been passed the event get the window.event
    e = e || window.event;

    var message = 'Any text will block the navigation and display a prompt';

    // For IE6-8 and Firefox prior to version 4
    if (e) 
    {
        e.returnValue = message;
    }

    // For Chrome, Safari, IE8+ and Opera 12+
    return message;
};

Sie können das nicht confirmOnPageExitüberprüfen lassen und null zurückgeben, wenn der Benutzer ohne die Nachricht fortfahren soll. Sie müssen das Ereignis noch entfernen, um es zuverlässig ein- und auszuschalten:

// Turn it on - assign the function that returns the string
window.onbeforeunload = confirmOnPageExit;

// Turn it off - remove the function entirely
window.onbeforeunload = null;

Ursprüngliche Antwort (gearbeitet im Jahr 2009)

So schalten Sie es ein:

window.onbeforeunload = "Are you sure you want to leave?";

So schalten Sie es aus:

window.onbeforeunload = null;

Denken Sie daran, dass dies kein normales Ereignis ist - Sie können sich nicht wie gewohnt daran binden.

Um nach Werten zu suchen? Das hängt von Ihrem Validierungsrahmen ab.

In jQuery könnte dies so etwas sein (sehr einfaches Beispiel):

$('input').change(function() {
    if( $(this).val() != "" )
        window.onbeforeunload = "Are you sure you want to leave?";
});
Keith
quelle
4
Das wäre ungefähr so: $ ('Eingabe: Text'). Change (function () {window.onbeforeunload = $ ('Eingabe: Text [Wert! = ""]'). Länge> 0? "Warnung": null ;});
Keith
1
Für eine einfache Überprüfung, oder Sie können eine komplexere Validierung für jede Änderung hinzufügen
Keith
1
Es ist erwähnenswert, dass die 'returnValue'-Methode die einzige im Standard angegebene Methode ist. Sie gilt also nicht nur für IE6-8, sondern für alle standardkonformen Browser (in diesem Fall ohne Chrome, Safari und Opera).
rmcclellan
3
Um die Warnung beim Senden des Formulars zu stoppen, habe ich verwendet $("#submit_button").click(function() { window.onbeforeunload = null; });. Ich habe ursprünglich das Onclick-Ereignis der Schaltfläche verwendet, aber es war nicht nur nicht so nett, sondern funktionierte auch nicht mit IE8.
Andy Beverley
1
@ AlikElzin-kilaka kannst du nicht. Wenn Sie den Popup-Text ändern möchten, müssen Sie ein eigenes benutzerdefiniertes Popup erstellen. Dies kann das window.onbeforeunloadEreignis jedoch nicht blockieren .
Keith
38

Der onbeforeunloadMicrosoft-Ismus kommt einer Standardlösung am nächsten, aber beachten Sie, dass die Browserunterstützung uneinheitlich ist. zB für Opera funktioniert es nur in Version 12 und höher (zum Zeitpunkt des Schreibens noch in der Beta).

Für maximale Kompatibilität müssen Sie außerdem mehr tun, als nur eine Zeichenfolge zurückzugeben, wie im Mozilla Developer Network erläutert .

Beispiel: Definieren Sie die folgenden zwei Funktionen zum Aktivieren / Deaktivieren der Navigationsaufforderung (siehe MDN-Beispiel):

function enableBeforeUnload() {
    window.onbeforeunload = function (e) {
        return "Discard changes?";
    };
}
function disableBeforeUnload() {
    window.onbeforeunload = null;
}

Definieren Sie dann ein Formular wie folgt:

<form method="POST" action="" onsubmit="disableBeforeUnload();">
    <textarea name="text"
              onchange="enableBeforeUnload();"
              onkeyup="enableBeforeUnload();">
    </textarea>
    <button type="submit">Save</button>
</form>

Auf diese Weise wird der Benutzer nur dann vor dem Wegnavigieren gewarnt, wenn er den Textbereich geändert hat, und wird nicht aufgefordert, wenn er das Formular tatsächlich sendet.

Søren Løvborg
quelle
1
Basierend auf Mozills Website unterstützen die neuesten Desktop-Browser dies jetzt: developer.mozilla.org/en/DOM/window.onbeforeunload
Hengjie
Microsoft-ism ist ein großartiger Begriff.
Luke Taylor
18

Mit JQuery ist dieses Zeug ziemlich einfach zu machen. Da kann man an Sets binden.

Es ist NICHT genug, um das Onbeforeunload durchzuführen. Sie möchten die Navigation nur dann auslösen, wenn jemand mit der Bearbeitung von Inhalten begonnen hat.

Sam Safran
quelle
2
Kann nicht scheinen, @jonstjohns Blog-Beiträge zu treffen. Vielleicht ist er ein Kumpel und zeigt uns in die richtige Richtung? : D
FLGMwt
14
=> 500 Interner Fehler. Aus diesem Grund sind Links auf SO veraltet. Downvoted bis behoben.
Loïc
Diese Webseite ist nicht verfügbar
Mateusz
2
Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert.
Bwest
2
Der ursprüngliche Link von Jon St John war defekt, daher habe ich ihn auf die Wayback Machine- Version aktualisiert . Der Inhalt des Links kann auf vielen anderen Websites kopiert gefunden werden, aber ich denke, es war besser, den von Sam hinzugefügten zu "bewahren"
Alvaro Montoro
14

jquerys 'beforeunload' hat bei mir super funktioniert

$(window).bind('beforeunload', function(){
    if( $('input').val() !== '' ){
        return "It looks like you have input you haven't submitted."
    }
});
Devon Peticolas
quelle
Bind ist veraltet und eine neuere Version von Code ähnlich diesem kann in dieser Antwort gesehen werden: stackoverflow.com/a/1889450/908677
Elijah Lofgren
12

Für neue Leute, die nach einer einfachen Lösung suchen, versuchen Sie einfach Areyousure.js

lawphotog
quelle
11

Dies ist eine einfache Möglichkeit, die Nachricht zu präsentieren, wenn Daten in das Formular eingegeben werden, und die Nachricht nicht anzuzeigen, wenn das Formular gesendet wird:

$(function () {
    $("input, textarea, select").on("input change", function() {
        window.onbeforeunload = window.onbeforeunload || function (e) {
            return "You have unsaved changes.  Do you want to leave this page and lose your changes?";
        };
    });
    $("form").on("submit", function() {
        window.onbeforeunload = null;
    });
})
Carl G.
quelle
8

Um die bereits erstaunliche Antwort von Keith zu erweitern :

Benutzerdefinierte Warnmeldungen

Um benutzerdefinierte Warnmeldungen zuzulassen, können Sie diese in eine Funktion wie die folgende einschließen:

function preventNavigation(message) {
    var confirmOnPageExit = function (e) {
        // If we haven't been passed the event get the window.event
        e = e || window.event;

        // For IE6-8 and Firefox prior to version 4
        if (e)
        {
            e.returnValue = message;
        }

        // For Chrome, Safari, IE8+ and Opera 12+
        return message;
    };
    window.onbeforeunload = confirmOnPageExit;
}

Rufen Sie dann einfach diese Funktion mit Ihrer benutzerdefinierten Nachricht auf:

preventNavigation("Baby, please don't go!!!");

Navigation wieder aktivieren

So aktivieren Sie Navigation, alles , was Sie tun müssen , ist festgelegt window.onbeforeunloadauf null. Hier ist es, eingewickelt in eine nette kleine Funktion, die überall aufgerufen werden kann:

function enableNavigation() {
    window.onbeforeunload = null;
}

Verwenden Sie jQuery, um dies zu Formelementen zu binden

Wenn Sie jQuery verwenden, kann dies leicht an alle Elemente eines Formulars wie folgt gebunden werden:

$("#yourForm :input").change(function() {
    preventNavigation("You have not saved the form. Any \
        changes will be lost if you leave this page.");
});

Dann, damit das Formular eingereicht werden kann:

$("#yourForm").on("submit", function(event) {
    enableNavigation();
});

Dynamisch modifizierte Formulare:

preventNavigation()und enableNavigation()kann nach Bedarf an andere Funktionen gebunden werden, z. B. das dynamische Ändern eines Formulars oder das Klicken auf eine Schaltfläche, die eine AJAX-Anforderung sendet. Dazu habe ich dem Formular ein verstecktes Eingabeelement hinzugefügt:

<input id="dummy_input" type="hidden" />

Jedes Mal, wenn ich verhindern möchte, dass der Benutzer weg navigiert, löse ich die Änderung an dieser Eingabe aus, um sicherzustellen, dass sie preventNavigation()ausgeführt wird:

function somethingThatModifiesAFormDynamically() {

    // Do something that modifies a form

    // ...
    $("#dummy_input").trigger("change");
    // ...
}
Mike
quelle
3

Hier versuchen Sie dies, es funktioniert 100%

<html>
<body>
<script>
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;
});
</script>
</body>
</html>
Braydon
quelle
3

Der Standard besagt, dass die Eingabeaufforderung gesteuert werden kann, indem das Ereignis vor dem Herunterladen abgebrochen oder der Rückgabewert auf einen Wert ungleich Null gesetzt wird . Außerdem wird angegeben, dass Autoren Event.preventDefault () anstelle von returnValue verwenden sollten und die dem Benutzer angezeigte Nachricht nicht anpassbar ist .

Ab 69.0.3497.92 hat Chrome den Standard nicht erfüllt. Es gibt jedoch einen Fehlerbericht und eine Überprüfung wird durchgeführt. In Chrome muss returnValue anhand des Ereignisobjekts festgelegt werden, nicht anhand des vom Handler zurückgegebenen Werts.

Es liegt in der Verantwortung des Autors, zu verfolgen, ob Änderungen vorgenommen wurden. Dies kann mit einer Variablen erfolgen oder indem sichergestellt wird, dass das Ereignis nur bei Bedarf behandelt wird.

window.addEventListener('beforeunload', function (e) {
    // Cancel the event as stated by the standard.
    e.preventDefault();
    // Chrome requires returnValue to be set.
    e.returnValue = '';
});
    
window.location = 'about:blank';

Trevor Karjanis
quelle
2

Wenn der Benutzer Änderungen am Formular vornimmt, wird ein boolesches Flag gesetzt. Wenn der Benutzer dann versucht, von der Seite weg zu navigieren, aktivieren Sie dieses Flag im Ereignis window.onunload . Wenn das Flag gesetzt ist, zeigen Sie die Nachricht an, indem Sie sie als Zeichenfolge zurückgeben. Wenn Sie die Nachricht als Zeichenfolge zurückgeben, wird ein Bestätigungsdialogfeld mit Ihrer Nachricht angezeigt.

Wenn Sie Ajax zum Festschreiben der Änderungen verwenden, können Sie das Flag auf setzen, falsenachdem die Änderungen festgeschrieben wurden (dh im Ajax-Erfolgsereignis).

Kirtan
quelle
1

Sie können onchangedem Textbereich (oder anderen Feldern) ein Ereignis hinzufügen , das eine Variable in JS festlegt. Wenn der Benutzer versucht, die Seite zu schließen (window.onunload), überprüfen Sie den Wert dieser Variablen und zeigen die Warnung entsprechend an.

Makram Saleh
quelle
1
Sie können dies nicht tun - alertund confirmwerden während window.onbeforeunloadund blockiert window.onunload(zumindest in der Version von Chrome auf meinem PC, aber wahrscheinlich auch in jedem Browser, der diese Handler jemals unterstützt).
Mark Amery
1

Basierend auf allen Antworten in diesem Thread habe ich den folgenden Code geschrieben und er hat bei mir funktioniert.

Wenn Sie nur einige Eingabe- / Textbereich-Tags haben, für die ein Onunload-Ereignis überprüft werden muss, können Sie HTML5-Datenattribute als zuweisen data-onunload="true"

für zB.

<input type="text" data-onunload="true" />
<textarea data-onunload="true"></textarea>

und das Javascript (jQuery) kann so aussehen:

$(document).ready(function(){
    window.onbeforeunload = function(e) {
        var returnFlag = false;
        $('textarea, input').each(function(){
            if($(this).attr('data-onunload') == 'true' && $(this).val() != '')
                returnFlag = true;
        });

        if(returnFlag)
            return "Sure you want to leave?";   
    };
});
Sagar Gala
quelle
2
Siehe auch "Aus bestimmten Gründen folgen Webkit-basierte Browser nicht der Spezifikation für das Dialogfeld" in der MDN- Dokumentation vor dem Herunterladen .
Arjan
1

Hier ist mein HTML

<!DOCTYPE HMTL>
<meta charset="UTF-8">
<html>
<head>
<title>Home</title>
<script type="text/javascript" src="script.js"></script>
</head>

 <body onload="myFunction()">
    <h1 id="belong">
        Welcome To My Home
    </h1>
    <p>
        <a id="replaceME" onclick="myFunction2(event)" href="https://www.ccis.edu">I am a student at Columbia College of Missouri.</a>
    </p>
</body>

Und so habe ich etwas Ähnliches in JavaScript gemacht

var myGlobalNameHolder ="";

function myFunction(){
var myString = prompt("Enter a name", "Name Goes Here");
    myGlobalNameHolder = myString;
    if (myString != null) {
        document.getElementById("replaceME").innerHTML =
        "Hello " + myString + ". Welcome to my site";

        document.getElementById("belong").innerHTML =
        "A place you belong";
    }   
}

// create a function to pass our event too
function myFunction2(event) {   
// variable to make our event short and sweet
var x=window.onbeforeunload;
// logic to make the confirm and alert boxes
if (confirm("Are you sure you want to leave my page?") == true) {
    x = alert("Thank you " + myGlobalNameHolder + " for visiting!");
}
}
Justin Stone
quelle
0

Dies kann einfach durch Setzen eines ChangeFlag auf true im onChange- Ereignis von TextArea erfolgen . Verwenden Sie Javascript, um das Bestätigungsdialogfeld basierend auf dem ChangeFlag- Wert anzuzeigen . Verwerfen Sie das Formular und navigieren Sie zur angeforderten Seite, wenn die Bestätigung true zurückgibt, andernfalls tun Sie nichts .

einfach hart
quelle
-1

Es gibt einen "onunload" -Parameter für das Body-Tag, von dem aus Sie Javascript-Funktionen aufrufen können. Wenn es false zurückgibt, wird das Wegnavigieren verhindert.

Stribika
quelle
13
Zum Glück funktioniert das nicht wirklich. Ansonsten würde ich es hassen, eine Seite mit zu besuchen <body onunload="return false;">.
Søren Løvborg