390 Stimmen

Wie kann ich das OnBeforeUnload-Dialogfeld außer Kraft setzen und durch mein eigenes ersetzen?

Ich muss die Benutzer vor nicht gespeicherten Änderungen warnen, bevor sie eine Seite verlassen (ein ziemlich häufiges Problem).

window.onbeforeunload = handler

Das funktioniert, aber es wird ein Standarddialog mit einer irritierenden Standardnachricht angezeigt, die meinen eigenen Text umschließt. Ich muss entweder vollständig die Standardnachricht ersetzen, so dass mein Text klar ist, oder (noch besser) ersetzen Sie den gesamten Dialog mit einem modalen Dialog mit jQuery.

Bisher bin ich gescheitert, und ich habe niemanden gefunden, der eine Antwort zu haben scheint. Ist das überhaupt möglich?

Javascript auf meiner Seite:

<script type="text/javascript">   
    window.onbeforeunload = closeIt;
</script>

Die Funktion closeIt():

function closeIt()
{
  if (changes == "true" || files == "true")
  {
      return "Here you can append a custom message to the default dialog.";
  }
}

Mit jQuery und jqModal habe ich versucht, diese Art von Sache (mit einem benutzerdefinierten Dialog bestätigen):

$(window).beforeunload(function () {
    confirm('new message: ' + this.href + ' !', this.href);
    return false;
});

was auch nicht funktioniert - ich kann anscheinend nicht mit dem beforeunload Veranstaltung.

334voto

Owen Punkte 79611

Sie können den Standarddialog nicht ändern für onbeforeunload Das Beste ist also, damit zu arbeiten.

window.onbeforeunload = function() {
    return 'You have unsaved changes!';
}

Hier ist eine Referenz zu diesem von Microsoft:

Wenn der Eigenschaft returnValue von window.event eine Zeichenfolge zugewiesen wird, erscheint ein Dialogfeld, in dem der Benutzer die Möglichkeit hat, auf der aktuellen Seite zu bleiben und die zugewiesene Zeichenfolge beizubehalten. Die Standardanweisung, die in dem Dialogfeld angezeigt wird, lautet: "Sind Sie sicher, dass Sie von dieser Seite weg navigieren möchten? ... Drücken Sie OK, um fortzufahren, oder Abbrechen, um auf der aktuellen Seite zu bleiben", kann nicht entfernt oder geändert werden.

Das Problem scheint zu sein:

  1. En onbeforeunload aufgerufen wird, nimmt er den Rückgabewert des Handlers als window.event.returnValue .
  2. Der Rückgabewert wird dann als Zeichenkette geparst (es sei denn, er ist null).
  3. Desde false als String geparst wird, wird das Dialogfeld ausgelöst, das dann eine entsprechende true / false .

Das Ergebnis ist, dass es keine Möglichkeit zu geben scheint, die false a onbeforeunload um zu verhindern, dass es zum Standarddialog wird.

Zusätzliche Hinweise zu jQuery:

  • Einstellen des Ereignisses in jQuery Mai problematisch sein, da dadurch andere onbeforeunload Ereignisse eintreten. Wenn Sie nur für Ihre Entladen-Ereignis auftreten möchten, würde ich Stick zu plain ol 'JavaScript für sie.
  • jQuery hat keine Abkürzung für onbeforeunload Sie müssen also das generische bind Syntax.

    $(window).bind('beforeunload', function() {} );

Bearbeiten 09/04/2018 Benutzerdefinierte Nachrichten in onbeforeunload-Dialogen sind seit Chrome-51 veraltet (siehe: Freigabemitteilung )

28voto

grebe Punkte 297

Was bei mir funktioniert hat, indem ich jQuery und getestet in IE8, Chrome und Firefox, ist:

$(window).bind("beforeunload",function(event) {
    if(hasChanged) return "You have unsaved changes";
});

Es ist wichtig, nichts zurückzugeben, wenn keine Eingabeaufforderung erforderlich ist, da es hier Unterschiede im Verhalten des IE und anderer Browser gibt.

24voto

Dan Power Punkte 1121

Während Sie in manchen Fällen nichts gegen die Box tun können, können Sie jemanden abfangen, der auf einen Link klickt. Für mich war dies für die meisten Szenarien die Mühe wert, und als Ausweichmöglichkeit habe ich das Entladeereignis belassen.

Ich habe Boxy anstelle des standardmäßigen jQuery-Dialogs verwendet, dieser ist hier verfügbar: http://onehackoranother.com/projects/jquery/boxy/

$(':input').change(function() {
    if(!is_dirty){
        // When the user changes a field on this page, set our is_dirty flag.
        is_dirty = true;
    }
});

$('a').mousedown(function(e) {
    if(is_dirty) {
        // if the user navigates away from this page via an anchor link, 
        //    popup a new boxy confirmation.
        answer = Boxy.confirm("You have made some changes which you might want to save.");
    }
});

window.onbeforeunload = function() {
if((is_dirty)&&(!answer)){
            // call this if the box wasn't shown.
    return 'You have made some changes which you might want to save.';
    }
};

Man könnte ein anderes Ereignis anhängen und mehr danach filtern, welche Art von Anker angeklickt wurde, aber das funktioniert für mich und das, was ich tun möchte, und dient als Beispiel für andere, die es verwenden oder verbessern können. Dachte, ich würde dies für diejenigen teilen, die diese Lösung wollen.

Ich habe den Code herausgeschnitten, daher kann es sein, dass er so nicht funktioniert.

9voto

user1164763 Punkte 151

1) Verwenden Sie onbeforeunload, nicht onunload.

2) Das Wichtigste ist, die Ausführung einer Return-Anweisung zu vermeiden. Damit meine ich nicht, dass Sie nicht aus Ihrem Handler zurückkehren sollen. Sie kehren zwar zurück, aber Sie müssen sicherstellen, dass Sie das Ende der Funktion erreichen und KEINE Rückkehranweisung ausführen. Unter diesen Bedingungen tritt der eingebaute Standarddialog nicht auf.

3) Sie können, wenn Sie onbeforeunload verwenden, einen Ajax-Aufruf in Ihrem unforeunload-Handler ausführen, um auf dem Server aufzuräumen, aber es muss ein synchroner sein, und Sie müssen auf die Antwort warten und sie in Ihrem onbeforeunload-Handler behandeln (immer noch unter Beachtung der Bedingung (2) oben). Ich tue dies und es funktioniert gut. Wenn Sie einen synchronen Ajax-Aufruf machen, wird alles aufgehalten, bis die Antwort zurückkommt. Wenn Sie einen asynchronen Ajax-Aufruf durchführen und denken, dass Sie sich nicht um die Antwort des Servers kümmern, wird die Seite weiter entladen und Ihr Ajax-Aufruf wird von diesem Prozess abgebrochen - einschließlich eines Remote-Skripts, falls es läuft.

8voto

Abhijeet Punkte 4906

Dies ist in Chrome nicht mehr möglich, um Spamming zu vermeiden, siehe javascript onbeforeunload zeigt keine benutzerdefinierte Nachricht für weitere Einzelheiten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X