Warnen Sie den Benutzer, bevor Sie eine Webseite mit nicht gespeicherten Änderungen verlassen

Lesezeit: 10 Minuten

Warnen Sie den Benutzer bevor Sie eine Webseite mit nicht
Khan

Ich habe einige Seiten mit Formularen in meiner Bewerbung.

Wie kann ich das Formular so sichern, dass jemand, wenn er wegnavigiert oder den Browser-Tab schließt, aufgefordert werden sollte, zu bestätigen, dass er das Formular wirklich mit nicht gespeicherten Daten verlassen möchte?

  • Diese Frage hier sollte die Antwort haben, nach der Sie suchen: stackoverflow.com/questions/1244535/…

    – Nexeros

    6. September 2011 um 8:58 Uhr

  • siehe stackoverflow.com/questions/140460/…

    – Atara

    17. Februar 2015 um 8:53 Uhr

  • Siehe auch: stackoverflow.com/q/821011/435605

    – AlikElzin-kilaka

    9. Februar 2016 um 6:17 Uhr

1646259911 768 Warnen Sie den Benutzer bevor Sie eine Webseite mit nicht
CodeCaster

Kurze, falsche Antwort:

Sie können dies tun, indem Sie Umgang mit der beforeunload Ereignis und Rückgabe einer Nicht-Null-Zeichenfolge:

window.addEventListener("beforeunload", function (e) {
    var confirmationMessage="It looks like you have been editing something. "
                            + 'If you leave before saving, your changes will be lost.';

    (e || window.event).returnValue = confirmationMessage; //Gecko + IE
    return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});

Das Problem bei diesem Ansatz ist das Das Absenden eines Formulars löst auch das Unload-Ereignis aus. Dies lässt sich leicht beheben, indem Sie das a-Flag hinzufügen, dass Sie ein Formular senden:

var formSubmitting = false;
var setFormSubmitting = function() { formSubmitting = true; };

window.onload = function() {
    window.addEventListener("beforeunload", function (e) {
        if (formSubmitting) {
            return undefined;
        }

        var confirmationMessage="It looks like you have been editing something. "
                                + 'If you leave before saving, your changes will be lost.';
        
        (e || window.event).returnValue = confirmationMessage; //Gecko + IE
        return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
    });
};

Dann Aufruf des Setters beim Absenden:

<form method="post" onsubmit="setFormSubmitting()">     
    <input type="submit" />
</form>

Aber lies weiter…

Lange, richtige Antwort:

Sie möchten diese Nachricht auch nicht anzeigen wenn der Benutzer nichts an Ihren Formularen geändert hat. Eine Lösung ist die Verwendung von beforeunload Event in Kombination mit einem “Dirty”-Flag, das den Prompt nur dann auslöst, wenn es wirklich relevant ist.

var isDirty = function() { return false; }

window.onload = function() {
    window.addEventListener("beforeunload", function (e) {
        if (formSubmitting || !isDirty()) {
            return undefined;
        }
        
        var confirmationMessage="It looks like you have been editing something. "
                                + 'If you leave before saving, your changes will be lost.';

        (e || window.event).returnValue = confirmationMessage; //Gecko + IE
        return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
    });
};
    

Nun zur Umsetzung der isDirty Methode gibt es verschiedene Ansätze.

Sie können jQuery und Formularserialisierung verwenden, aber dieser Ansatz hat einige Mängel. Zuerst müssen Sie den Code ändern, um auf jedem Formular zu arbeiten ($("form").each() tun), aber das größte Problem ist das von jQuery serialize() funktioniert nur bei benannten, nicht deaktivierten Elementen, sodass das Ändern eines deaktivierten oder unbenannten Elements nicht das Dirty-Flag auslöst. Dafür gibt es Problemumgehungen, z. B. das Festlegen von schreibgeschützten Steuerelementen anstelle des Aktivierens, Serialisierens und erneuten Deaktivierens der Steuerelemente.

Ereignisse scheinen also der richtige Weg zu sein. Sie können versuchen, auf Tastendrücke zu hören. Diese Veranstaltung weist einige Probleme auf:

  • Wird nicht bei Kontrollkästchen, Optionsfeldern oder anderen Elementen ausgelöst, die durch Mauseingabe geändert werden.
  • Wird für irrelevante Tastendrücke wie die ausgelöst Strg Schlüssel.
  • Wird nicht auf Werte ausgelöst, die durch JavaScript-Code festgelegt wurden.
  • Wird nicht beim Ausschneiden oder Einfügen von Text über Kontextmenüs ausgelöst.
  • Funktioniert nicht für virtuelle Eingaben wie Datumsauswahl oder Verschönerungen von Kontrollkästchen/Radiobuttons, die ihren Wert in einer versteckten Eingabe über JavaScript speichern.

Die change Das Ereignis wird auch nicht bei Werten ausgelöst, die aus JavaScript-Code festgelegt wurden, und funktioniert daher auch nicht für virtuelle Eingaben.

Bindung der input Veranstaltung für alle inputs (und textareas und selects) auf Ihrer Seite funktioniert nicht mit älteren Browsern und unterstützt, wie alle oben genannten Lösungen zur Ereignisbehandlung, das Rückgängigmachen nicht. Wenn ein Benutzer ein Textfeld ändert und dies dann rückgängig macht oder ein Kontrollkästchen aktiviert und deaktiviert, wird das Formular immer noch als fehlerhaft betrachtet.

Und wenn Sie weitere Verhaltensweisen implementieren möchten, z. B. das Ignorieren bestimmter Elemente, müssen Sie noch mehr tun.

Das Rad nicht neu erfinden:

Bevor Sie also über die Implementierung dieser Lösungen und aller erforderlichen Problemumgehungen nachdenken, sollten Sie sich darüber im Klaren sein, dass Sie das Rad neu erfinden und dazu neigen, auf Probleme zu stoßen, die andere bereits für Sie gelöst haben.

Wenn Ihre Anwendung bereits jQuery verwendet, können Sie auch getesteten, gepflegten Code verwenden, anstatt Ihren eigenen zu erstellen, und für all dies eine Bibliothek eines Drittanbieters verwenden.

jquery.dirty (empfohlen von @troseman in den Kommentaren) bietet Funktionen, um richtig zu erkennen, ob ein Formular geändert wurde oder nicht, und um zu verhindern, dass der Benutzer die Seite verlässt, während eine Eingabeaufforderung angezeigt wird. Es hat auch andere nützliche Funktionen wie das Zurücksetzen des Formulars und das Festlegen des aktuellen Status des Formulars als “sauberen” Status. Beispielnutzung:

$("#myForm").dirty({preventLeaving: true});

Ein älteres, derzeit aufgegebenes Projekt ist Sind Sie sicher? Plugin, was auch super funktioniert; siehe ihre Demoseite. Beispielnutzung:

<script src="jquery.are-you-sure.js"></script>

<script>
  $(function() {
    $('#myForm').areYouSure(
      {
        message: 'It looks like you have been editing something. '
               + 'If you leave before saving, your changes will be lost.'
      }
    );
  });
  
</script>

Benutzerdefinierte Nachrichten werden nicht überall unterstützt

Beachten Sie, dass Firefox 4 bereits seit 2011 keine benutzerdefinierten Nachrichten in diesem Dialogfeld unterstützt. Ab April 2016 wird Chrome 51 ausgerollt in denen auch benutzerdefinierte Nachrichten entfernt werden.

An anderer Stelle auf dieser Seite gibt es einige Alternativen, aber ich denke, ein Dialog wie dieser ist klar genug:

Möchten Sie diese Seite verlassen?

Von Ihnen vorgenommene Änderungen werden möglicherweise nicht gespeichert.

Verlassen Bleibe

  • Beachten Sie, dass die Verwendung benutzerdefinierter Zeichenfolgen in Chrome nicht mehr funktioniert. chromestatus.com/feature/5349061406228480

    – Amann

    4. Mai 2017 um 12:58 Uhr

  • Ja, das ist im letzten Abschnitt meiner Antwort beschrieben.

    – CodeCaster

    4. Mai 2017 um 13:00 Uhr


  • @Chris das liegt daran, dass Angular das DOM manipuliert, um die Seite zu ändern, ohne vom aktuellen Dokument wegzunavigieren.

    – CodeCaster

    4. Mai 2017 um 18:07 Uhr

  • Seien Sie gewarnt, dass jQuery areYouSure seit 2014 aufgegeben wurde (57 offene Probleme auf GitHub) , es ist meiner Erfahrung nach voller Fehler, es mag zunächst so aussehen, als ob es funktioniert, aber nach einigen schnellen Tests wurde mir klar, dass es nicht immer funktioniert. Würde das überhaupt nicht empfehlen

    – Kennzeichen

    10. Januar 2018 um 21:38 Uhr


  • @JacopoStanchi Ich habe leider keine gefunden. Und ich meine, ich habe ziemlich viel gesucht – aber das war am 10. Januar, also hat vielleicht jemand etwas geschrieben, aber ich bezweifle es. Am besten implementieren Sie es selbst – es ist nicht das, was Sie hören möchten, tut mir leid. (Aber zumindest werden Sie keine Überraschungen erleben, wie ich es mit jQuery areYouSure getan habe.) Und wer weiß, vielleicht könnten Sie es sogar Open Source machen und Ihre Implementierung würde mit anderen geteilt werden;)

    – Kennzeichen

    6. Juli 2018 um 14:38 Uhr


Überprüfen Sie das JavaScript onbeforeunload-Ereignis. Es ist nicht standardmäßiges JavaScript, das von Microsoft eingeführt wurde, aber es funktioniert in den meisten Browsern und ihre Onbeforeunload-Dokumentation enthält weitere Informationen und Beispiele.

  • Ich denke, es ist jetzt zu Standards geworden. >> Das Ereignis wurde ursprünglich von Microsoft im Internet Explorer 4 eingeführt und in der HTML5-Spezifikation standardisiert.

    – v

    9. Juli 2018 um 16:06 Uhr

Warnen Sie den Benutzer bevor Sie eine Webseite mit nicht
Wasim A.

über jquery

$('#form').data('serialize',$('#form').serialize()); // On load save form current state

$(window).bind('beforeunload', function(e){
    if($('#form').serialize()!=$('#form').data('serialize'))return true;
    else e=null; // i.e; if form state change show warning box, else don't show it.
});

Sie können die Google JQuery Form Serialize-Funktion verwenden, die alle Formulareingaben sammelt und in einem Array speichert. Ich denke diese Erklärung reicht 🙂

  • Verwenden Sie #form nicht als Formular-ID, da das Fenster ein Objekt mit dem Namen form erstellt 🙂

    – mdikici

    25. Juli 2014 um 15:26 Uhr

  • Überprüfen Sie hier, ob es bei Ihnen nicht funktioniert: stackoverflow.com/questions/7080269/…

    – Leniel Maccaferri

    28. Oktober 2014 um 1:38 Uhr

1646259913 529 Warnen Sie den Benutzer bevor Sie eine Webseite mit nicht
Eli Gray

Universelle Lösung, die keine Konfiguration erfordert und automatisch alle Eingabeänderungen erkennt, einschließlich inhaltsveränderbarer Elemente:

"use strict";
(() => {
const modified_inputs = new Set;
const defaultValue = "defaultValue";
// store default values
addEventListener("beforeinput", (evt) => {
    const target = evt.target;
    if (!(defaultValue in target || defaultValue in target.dataset)) {
        target.dataset[defaultValue] = ("" + (target.value || target.textContent)).trim();
    }
});
// detect input modifications
addEventListener("input", (evt) => {
    const target = evt.target;
    let original;
    if (defaultValue in target) {
        original = target[defaultValue];
    } else {
        original = target.dataset[defaultValue];
    }
    if (original !== ("" + (target.value || target.textContent)).trim()) {
        if (!modified_inputs.has(target)) {
            modified_inputs.add(target);
        }
    } else if (modified_inputs.has(target)) {
        modified_inputs.delete(target);
    }
});
// clear modified inputs upon form submission
addEventListener("submit", (evt) => {
    modified_inputs.clear();
    // to prevent the warning from happening, it is advisable
    // that you clear your form controls back to their default
    // state with evt.target.reset() or form.reset() after submission
});
// warn before closing if any inputs are modified
addEventListener("beforeunload", (evt) => {
    if (modified_inputs.size) {
        const unsaved_changes_warning = "Changes you made may not be saved.";
        evt.returnValue = unsaved_changes_warning;
        return unsaved_changes_warning;
    }
});
})();

1646259913 78 Warnen Sie den Benutzer bevor Sie eine Webseite mit nicht
Eerik Sven Puudist

Aufbauend auf der hervorragenden Idee von Wasim A., Serialisierung zu verwenden. Das Problem dabei war, dass die Warnung auch beim Absenden des Formulars angezeigt wurde. Dies wurde hier behoben.

var isSubmitting = false

$(document).ready(function () {
    $('form').submit(function(){
        isSubmitting = true
    })

    $('form').data('initial-state', $('form').serialize());

    $(window).on('beforeunload', function() {
        if (!isSubmitting && $('form').serialize() != $('form').data('initial-state')){
            return 'You have unsaved changes which will not be saved.'
        }
    });
})

Es wurde in Chrome und IE 11 getestet.

  • Wasim A und Eerik Sven Puudist – Danke. Ich habe id für das Formular und id für meine Schaltfläche “Speichern” verwendet, da alle meine Schaltflächen vom Typ “submit

    und wenige mehr alle geben Submit ab Daher ersetzt .Submit( durch spezifisches Klicken $(‘#save’).click(function(){ isSubmitting = true }) Verwenden Sie ‘#marksform’ anstelle von ‘form’

    – Jayanta

    25. Mai 2019 um 14:02 Uhr

  • Ich habe auch die ID anstelle des Formulars verwendet und es funktioniert auch.

    – Jeric Cruz

    28. Juli 2020 um 5:45 Uhr

Basierend auf den vorherigen Antworten und aus verschiedenen Stellen im Stapelüberlauf zusammengeschustert, habe ich mir hier die Lösung ausgedacht, die den Fall behandelt, wenn Sie Ihre Änderungen tatsächlich einreichen möchten:

window.thisPage = window.thisPage || {};
window.thisPage.isDirty = false;

window.thisPage.closeEditorWarning = function (event) {
    if (window.thisPage.isDirty)
        return 'It looks like you have been editing something' +
               ' - if you leave before saving, then your changes will be lost.'
    else
        return undefined;
};

$("form").on('keyup', 'textarea', // You can use input[type=text] here as well.
             function () { 
                 window.thisPage.isDirty = true; 
             });

$("form").submit(function () {
    QC.thisPage.isDirty = false;
});
window.onbeforeunload = window.thisPage.closeEditorWarning;

Es ist erwähnenswert, dass IE11 dies zu erfordern scheint closeEditorWarning Funktion zurück undefined damit es keinen Alarm anzeigt.

  • Wasim A und Eerik Sven Puudist – Danke. Ich habe id für das Formular und id für meine Schaltfläche “Speichern” verwendet, da alle meine Schaltflächen vom Typ “submit

    und wenige mehr alle geben Submit ab Daher ersetzt .Submit( durch spezifisches Klicken $(‘#save’).click(function(){ isSubmitting = true }) Verwenden Sie ‘#marksform’ anstelle von ‘form’

    – Jayanta

    25. Mai 2019 um 14:02 Uhr

  • Ich habe auch die ID anstelle des Formulars verwendet und es funktioniert auch.

    – Jeric Cruz

    28. Juli 2020 um 5:45 Uhr

Der folgende Einzeiler hat für mich funktioniert.

window.onbeforeunload = s => modified ? "" : null;

Einfach einstellen modified zu wahr oder falsch je nach Stand Ihrer Bewerbung.

  • Einige Vorschläge: Geben Sie eine benutzerdefinierte Nachricht anstelle einer leeren Zeichenfolge zurück, da einige Browser sie anzeigen (z. B. Edge), und kehren Sie zurück undefined eher, als null da IE ‘null’ ausgibt, wenn modified ist falsch.

    – Kevin Lee

    17. Juli 2017 um 5:50 Uhr

  • wie sieht es mit mobilen Geräten aus? Mein Verständnis ist, dass IOS-Geräte onbeforeunload nicht würdigen.

    – Jaybro

    10. April 2018 um 18:59 Uhr

916760cookie-checkWarnen Sie den Benutzer, bevor Sie eine Webseite mit nicht gespeicherten Änderungen verlassen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy