it-swarm.com.de

Wie erfasse ich das Ereignis zum Schließen des Browserfensters?

Ich möchte das Ereignis zum Schließen des Browserfensters/der Registerkarte erfassen. Ich habe folgendes mit jQuery versucht:

jQuery(window).bind(
    "beforeunload", 
    function() { 
        return confirm("Do you really want to close?") 
    }
)

Aber es funktioniert auch beim Einreichen von Formularen, was ich nicht will. Ich möchte ein Ereignis, das nur ausgelöst wird, wenn der Benutzer das Fenster schließt.

141
khelll

Das Ereignis beforeunload wird immer dann ausgelöst, wenn der Benutzer Ihre Seite aus irgendeinem Grund verlässt.

Es wird beispielsweise ausgelöst, wenn der Benutzer ein Formular sendet, auf einen Link klickt, das Fenster (oder den Tabulator) schließt oder mithilfe der Adressleiste, des Suchfelds oder eines Lesezeichens zu einer neuen Seite wechselt.

Sie können Formularübermittlungen und Hyperlinks (außer von anderen Frames) mit folgendem Code ausschließen:

var inFormOrLink;
$('a').on('click', function() { inFormOrLink = true; });
$('form').on('submit', function() { inFormOrLink = true; });

$(window).on("beforeunload", function() { 
    return inFormOrLink ? "Do you really want to close?" : null; 
})

Versuchen Sie Folgendes für jQuery-Versionen, die älter als 1.7 sind:

var inFormOrLink;
$('a').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });

$(window).bind("beforeunload", function() { 
    return inFormOrLink ? "Do you really want to close?" : null; 
})

Die Methode live funktioniert nicht mit dem Ereignis submit. Wenn Sie also ein neues Formular hinzufügen, müssen Sie den Handler ebenfalls daran binden.

Beachten Sie, dass Sie die Bestätigungsaufforderung verlieren, wenn eine andere Ereignisbehandlungsroutine die Übermittlung oder Navigation abbricht, wenn das Fenster später tatsächlich geschlossen wird. Sie können dies beheben, indem Sie die Zeit in den Ereignissen submit und click aufzeichnen und überprüfen, ob beforeunload länger als ein paar Sekunden später auftritt.

198
SLaks

Vielleicht können Sie einfach die beforeunload Ereignisbehandlungsroutine in der submit Ereignisbehandlungsroutine des Formulars aufheben:

jQuery('form').submit(function() {
    jQuery(window).unbind("beforeunload");
    ...
});
44
karim79

Verwenden Sie für eine browserübergreifende Lösung (getestet in Chrome 21, IE9, FF15)) den folgenden Code, der eine leicht überarbeitete Version des Slaks-Codes darstellt:

var inFormOrLink;
$('a').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });

$(window).bind('beforeunload', function(eventObject) {
    var returnValue = undefined;
    if (! inFormOrLink) {
        returnValue = "Do you really want to close?";
    }
    eventObject.returnValue = returnValue;
    return returnValue;
}); 

Beachten Sie, dass seit Firefox 4 die Meldung "Möchten Sie wirklich schließen?" wird nicht angezeigt. FF zeigt nur eine allgemeine Meldung an. Siehe Hinweis in https://developer.mozilla.org/en-US/docs/DOM/window.onbeforeunload

15
desm
window.onbeforeunload = function () {
    return "Do you really want to close?";
};
11

Für eine Lösung, die mit Steuerelementen von Drittanbietern wie Telerik (z. B. RadComboBox) und DevExpress, die die Anchor-Tags aus verschiedenen Gründen verwenden, gut funktioniert, sollten Sie den folgenden Code verwenden, der eine leicht überarbeitete Version des Desm-Codes mit einem besseren Selektor für Selbst ist Targeting von Anker-Tags:

var inFormOrLink;
$('a[href]:not([target]), a[href][target=_self]').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });

$(window).bind('beforeunload', function(eventObject) {
    var returnValue = undefined;
    if (! inFormOrLink) {
        returnValue = "Do you really want to close?";
    }
    eventObject.returnValue = returnValue;
    return returnValue;
});
4
PLT

Meine Antwort zielt darauf ab, einfache Benchmarks bereitzustellen.

WIE MAN

Siehe @ SLaks Antwort .

$(window).on("beforeunload", function() { 
    return inFormOrLink ? "Do you really want to close?" : null; 
})

Wie lange dauert es, bis der Browser Ihre Seite endgültig geschlossen hat?

Immer wenn ein Benutzer die Seite schließt (x Taste oder CTRL + W) führt der Browser den angegebenen beforeunload Code aus, jedoch nicht auf unbestimmte Zeit. Die einzige Ausnahme ist das Bestätigungsfeld (return 'Do you really want to close?), der auf die Antwort des Benutzers wartet.

Chrome : 2 Sekunden.
Firefox : ∞ (oder Doppelklick oder Force On Close)
Kante : ∞ (oder Doppelklick)
Explorer 11 : 0 Sekunden.
Safari : [~ # ~] todo [~ # ~]

Was wir getestet haben:

  • Ein Node.js Express-Server mit Anforderungsprotokoll
  • Die folgende kurze HTML-Datei

Es werden so viele Anfragen wie möglich gesendet, bevor der Browser seine Seite (synchron) herunterfährt.

<html>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script>
    function request() {
        return $.ajax({
            type: "GET",
            url: "http://localhost:3030/" + Date.now(),
            async: true
        }).responseText;
    }
    window.onbeforeunload = () => {
        while (true) {
            request();
        }
        return null;
    }
    </script>
</body>
</html>

Chrome-Ausgabe:

GET /1480451321041 404 0.389 ms - 32  
GET /1480451321052 404 0.219 ms - 32  
...  
GET /hello/1480451322998 404 0.328 ms - 32

1957ms ≈ 2 seconds // we assume it's 2 seconds since requests can take few milliseconds to be sent.
4
zurfyx

Ich habe Slaks answer verwendet, aber das hat nicht so funktioniert, wie es ist, da der Rückgabewert onbeforeunload als Zeichenfolge analysiert und dann im Bestätigungsfeld des Browsers angezeigt wird. So wurde der Wert true angezeigt, wie "true".

Nur die Rückgabe hat funktioniert. Hier ist mein Code

var preventUnloadPrompt;
var messageBeforeUnload = "my message here - Are you sure you want to leave this page?";
//var redirectAfterPrompt = "http://www.google.co.in";
$('a').live('click', function() { preventUnloadPrompt = true; });
$('form').live('submit', function() { preventUnloadPrompt = true; });
$(window).bind("beforeunload", function(e) { 
    var rval;
    if(preventUnloadPrompt) {
        return;
    } else {
        //location.replace(redirectAfterPrompt);
        return messageBeforeUnload;
    }
    return rval;
})
3
kapad

Leider wird das Ereignis ausgelöst, unabhängig davon, ob es sich um ein Neuladen, eine neue Seitenumleitung oder ein Schließen des Browsers handelt. Eine Alternative ist, die ID zu erfassen, die das Ereignis auslöst, und wenn es sich um ein Formular handelt, keine Funktion auszulösen, und wenn es nicht die ID des Formulars ist, dann tun Sie, was Sie tun möchten, wenn die Seite geschlossen wird. Ich bin mir nicht sicher, ob das auch direkt möglich und mühsam ist.

Sie können noch einige Kleinigkeiten erledigen, bevor der Kunde die Registerkarte schließt. Javascript Browser erkennen Tab schliessen/Browser schliessen Aber wenn Ihre Liste der Aktionen umfangreich ist und der Tab geschlossen wird, bevor er fertig ist, sind Sie hilflos. Sie können es versuchen, aber mit meiner Erfahrung nicht davon abhängen.

window.addEventListener("beforeunload", function (e) {
  var confirmationMessage = "\o/";
  /* Do you small action code here */
  (e || window.event).returnValue = confirmationMessage; //Gecko + IE
  return confirmationMessage;                            //Webkit, Safari, Chrome
});

https://developer.mozilla.org/en-US/docs/Web/Reference/Events/beforeunload?redirectlocale=en-US&redirectslug=DOM/Mozilla_event_reference/beforeunload

1
Gary
jQuery(window).bind(
                    "beforeunload",
                      function (e) {
                          var activeElementTagName = e.target.activeElement.tagName;
                          if (activeElementTagName != "A" && activeElementTagName != "INPUT") {
                              return "Do you really want to close?";
                          }
                      })
1
Coding man

Vielleicht könnten Sie mit OnSubmit umgehen und ein Flag setzen, das Sie später in Ihrem OnBeforeUnload-Handler überprüfen.

1
i_am_jorf

Wenn Ihre Formularübermittlung sie auf eine andere Seite weiterleitet (wie ich annehme, und daher beforeunload auslöst), können Sie versuchen, Ihre Formularübermittlung in einen Ajax-Aufruf umzuwandeln. Auf diese Weise verlassen sie Ihre Seite nicht, wenn sie das Formular absenden, und Sie können Ihren beforeunload Bindungscode verwenden, wie Sie möchten.

0
idrumgood

Mein Problem: Das Ereignis "onbeforeunload" würde nur bei einer ungeraden Anzahl von Einsendungen (Klicks) ausgelöst. Ich hatte eine Kombination von Lösungen aus ähnlichen Threads in SO), damit meine Lösung funktioniert. Nun, mein Code wird sprechen.

<!--The definition of event and initializing the trigger flag--->


$(document).ready(function() {
updatefgallowPrompt(true);
window.onbeforeunload = WarnUser;   
}

function WarnUser() {
var allowPrompt = getfgallowPrompt();
    if(allowPrompt) {
    saveIndexedDataAlert();
    return null;
    } else {
        updatefgallowPrompt(true);
        event.stopPropagation
    }
}

<!--The method responsible for deciding weather the unload event is triggered from submit or not--->
function saveIndexedDataAlert() {
    var allowPrompt = getfgallowPrompt();
    var lenIndexedDocs = parseInt($('#sortable3 > li').size()) + parseInt($('#sortable3 > ul').size());

    if(allowPrompt && $.trim(lenIndexedDocs) > 0) {
        event.returnValue = "Your message";
    } else {
        event.returnValue = "   ";
        updatefgallowPrompt(true);
    }
}

<!---Function responsible to reset the trigger flag---->
$(document).click(function(event) {  
$('a').live('click', function() { updatefgallowPrompt(false); });
 });

<!--getter and setter for the flag---->
function updatefgallowPrompt (allowPrompt){ //exit msg dfds
    $('body').data('allowPrompt', allowPrompt); 
}   

function getfgallowPrompt(){        
    return $('body').data('allowPrompt');   
}
0
Yoosaf Abdulla

Versuchen Sie dies auch

window.onbeforeunload = function ()
{       
    if (pasteEditorChange) {
        var btn = confirm('Do You Want to Save the Changess?');
           if(btn === true ){
               SavetoEdit();//your function call
           }
           else{
                windowClose();//your function call
           }
    }  else { 
        windowClose();//your function call
    }
};
0
Bhaskara Arani

Ab jQuery 1.7 ist die Methode .live () veraltet. Verwenden Sie .on (), um Ereignishandler anzuhängen. Benutzer älterer jQuery-Versionen sollten .delegate () anstelle von .live () verwenden.

$(window).bind("beforeunload", function() {
    return true || confirm("Do you really want to close?"); 
}); 

auf Vollständig oder Link

$(window).unbind();
0
Tom