jquery beforeunload beim Schließen (nicht Verlassen) der Seite?

82

Wie kann ich anzeigen "Möchten Sie die Seite wirklich verlassen?" Wenn der Benutzer tatsächlich versucht, die Seite zu schließen (klicken Sie auf die X-Schaltfläche im Browserfenster oder auf der Registerkarte), nicht, wenn er versucht, von der Seite weg zu navigieren (klicken Sie auf einen anderen Link).

Mein Kunde möchte, dass eine Meldung angezeigt wird, wenn der Benutzer versucht, die Seite zu schließen. "Möchten Sie die Seite wirklich verlassen? Sie haben noch Artikel in Ihrem Warenkorb."

Wird leider $(window).bind('beforeunload')nicht nur ausgelöst, wenn der Benutzer die Seite schließt.

jQuery:

function checkCart() { 
  $.ajax({
    url : 'index.php?route=module/cart/check',
    type : 'POST',
    dataType : 'json',
    success : function (result) {
       if (result) {
        $(window).bind('beforeunload', function(){
          return 'leave?';
        });
       }
    }
  })
}
Krise
quelle
1
Das kannst du nicht. Sie können den Unterschied zwischen dem Schließen des Browsers und dem Weg navigieren des Benutzers von Ihrer Seite nicht programmgesteuert feststellen.
Meagar
@Cris Welcher Fehler ist aufgetreten?
Padmanathan J
Ihre Nachricht enthält Code, der auf eine laufende Ajax-Operation hinweist. Gibt es einige davon, die wir berücksichtigen müssen? (weil Sie ihn mit Ausnahme dieses Codes nicht ausdrücklich erwähnt haben)
Cyril N.
Sie können nicht feststellen, ob ein Fenster geschlossen ist oder zu einer anderen URL navigiert. Wenn Sie einen Browser mit mehreren Registerkarten verwenden, spielt dies keine Rolle. Wenn Sie jedoch die Hash-Navigation verwenden (z. B. yourdomain.com/#path=/index) / news & id = 1 ), Sie können es schaffen, Javascript zu werfen, wenn Sie navigieren
Alphakevin

Antworten:

144

Sie können dies mit JQuery tun .

Zum Beispiel ,

<a href="your URL" id="navigate"> click here </a>

Dein JQueryWille ist,

$(document).ready(function(){

    $('a').on('mousedown', stopNavigate);

    $('a').on('mouseleave', function () {
           $(window).on('beforeunload', function(){
                  return 'Are you sure you want to leave?';
           });
    });
});

function stopNavigate(){    
    $(window).off('beforeunload');
}

Und um die Nachricht "Nachricht hinterlassen " zu erhalten,

$(window).on('beforeunload', function(){
      return 'Are you sure you want to leave?';
});

$(window).on('unload', function(){

         logout();

});

Diese Lösung funktioniert in allen Browsern und ich habe sie getestet.

Menschliches Wesen
quelle
2
Dies ist eine gute (Sie sollten sie wahrscheinlich auch beachten onsubmit), aber sie funktioniert nicht für die Schaltflächen "Zurück" und "Weiter" des Browsers. Ich gehe davon aus, dass es dafür keine ideale Lösung gibt.
Noseratio
Code ist in Ordnung. Ich möchte die Funktion logout () ausführen, wenn der Benutzer auf die Pop-Schaltfläche "Diese Seite verlassen" klickt. Aber wie kann ich feststellen, ob der Benutzer auf "Diese Seite verlassen" geklickt hat oder nicht?
Bit_hunter
1
Dies $(window).on('unload', function()wird in Safari nicht ausgeführt.
Aarohi Kulkarni
1
Wird beforeunloadausgelöst, wenn der Browser aufgrund eines Herunterfahrens des Betriebssystems geschlossen wird?
techie_28
4
Sie können in Chrome oder Firefox keine benutzerdefinierten Nachrichten mehr bereitstellen (weil sie Betrug verhindern möchten): developer.google.com/web/updates/2016/04/…
Adam
12

Versuchen Sie es mit Javascript in Ihrem Ajax

window.onbeforeunload = function(){
  return 'Are you sure you want to leave?';
};

Referenz - Link

Beispiel 2:

document.getElementsByClassName('eStore_buy_now_button')[0].onclick = function(){
    window.btn_clicked = true;
};
window.onbeforeunload = function(){
    if(!window.btn_clicked){
        return 'You must click "Buy Now" to make payment and finish your order. If you leave now your order will be canceled.';
    }
};

Hier wird der Benutzer jedes Mal benachrichtigt, wenn er die Seite verlässt, bis er auf die Schaltfläche klickt.

DEMO: http://jsfiddle.net/DerekL/GSWbB/show/

Padmanathan J.
quelle
12

Gutschrift sollte hier gehen: Wie erkennt man, ob ein Link angeklickt wurde, als window.onbeforeunload ausgelöst wurde?

Grundsätzlich fügt die Lösung einen Listener hinzu, um zu erkennen, ob ein Link oder ein Fenster das Entladeereignis ausgelöst hat.

var link_was_clicked = false;
document.addEventListener("click", function(e) {
   if (e.target.nodeName.toLowerCase() === 'a') {
      link_was_clicked = true;
   }
}, true);

window.onbeforeunload = function(e) {
    if(link_was_clicked) {
        return;
    }
    return confirm('Are you sure?');
}
Andy Merhaut
quelle
2

Wie hier angegeben, https://stackoverflow.com/a/1632004/330867 , können Sie es implementieren, indem Sie "filtern", was den Ausgang dieser Seite verursacht.

Wie in den Kommentaren erwähnt, ist hier eine neue Version des Codes in der anderen Frage, die auch die Ajax-Anfrage enthält, die Sie in Ihrer Frage stellen:

var canExit = true;

// For every function that will call an ajax query, you need to set the var "canExit" to false, then set it to false once the ajax is finished.

function checkCart() {
  canExit = false;
  $.ajax({
    url : 'index.php?route=module/cart/check',
    type : 'POST',
    dataType : 'json',
    success : function (result) {
       if (result) {
        canExit = true;
       }
    }
  })
}

$(document).on('click', 'a', function() {canExit = true;}); // can exit if it's a link
$(window).on('beforeunload', function() {
    if (canExit) return null; // null will allow exit without a question
    // Else, just return the message you want to display
    return "Do you really want to close?";
});

Wichtig : Sie sollten keine globale Variable definieren (hier canExit), dies ist hier für eine einfachere Version.

Beachten Sie, dass Sie die Bestätigungsmeldung nicht vollständig überschreiben können (zumindest in Chrome). Die von Ihnen zurückgegebene Nachricht wird nur der von Chrome angegebenen Nachricht vorangestellt. Hier ist der Grund: Wie kann ich den OnBeforeUnload-Dialog überschreiben und durch meinen eigenen ersetzen?

Cyril N.
quelle
3
Ab jQuery 1.7 .liveist veraltet. Stattdessen $(document).on('click', 'a', ...) sollte das verwendet werden. .onist im Allgemeinen der bevorzugte Weg gegenüber den alten Funktionen, so wie .bindes wäre $('form').on('submit', ...).
t.niese
Ich bin mir ziemlich sicher, dass diese Antwort nicht mehr browserübergreifend ist. Jemand hat es getestet?
A. Wolff
Wie gesagt, ich habe nur den Code kopiert / eingefügt. Ich werde die Antwort mit einer neuesten Version bearbeiten
Cyril N.
Vielen Dank, aber leider wird die Bestätigung nicht angezeigt, wenn ich den Tab schließe.
Cris
.. und ein großer Fehler, den ich gemacht habe (klicken Sie statt vor dem Entladen als Dokumentereignis).
Cyril N.
-1

Versuchen Sie dies, ajaxindem Sie Daten über die return-Anweisung laden und über diese anzeigen.

<script type="text/javascript">
function closeWindow(){

    var Data = $.ajax({
        type : "POST",
        url : "file.txt",  //loading a simple text file for sample.
        cache : false,
        global : false,
        async : false,
        success : function(data) {
            return data;
        }

    }).responseText;


    return "Are you sure you want to leave the page? You still have "+Data+" items in your shopping cart";
}

window.onbeforeunload = closeWindow;
</script>
Raduns
quelle
1
Es ist keine gute Idee, Ihren Benutzer jedes Mal, wenn er auf einen Link auf Ihrer Website klickt, auf die Antwort eines synchronen AJAX-Anrufs warten zu lassen.
Mattalxndr