Erfassen Sie das Schließereignis des Popup-Fensters in JavaScript

74

Ich muss eine Aktion ausführen, bevor ein Popup-Fenster (mit window.open) geschlossen wird.

So etwas wird gut sein:

var new_window = window.open('some url')
new_window.onBeforeUnload = function(){ my code}

Wie kann ich das erreichen?

xiaohan2012
quelle

Antworten:

89

Ihr Beispiel funktioniert so lange, wie sich die URL des Popup-Fensters in derselben Domäne wie die übergeordnete Seite befindet und Sie das Ereignis in Kleinbuchstaben ändern:

var new_window = window.open('some url')
new_window.onbeforeunload = function(){ /* my code */ }
glortho
quelle
6
Was ist, wenn sich das neu geöffnete Fenster nicht in derselben Domäne wie das übergeordnete Fenster befindet? Gibt es einen Hack?
Xiaohan2012
13
Das Beste, was Sie tun können, ist, ein Dokument in Ihrer Domain zu öffnen, das dann die Remote-URL in einen Iframe lädt oder sie über Serverskripte einliest und von dort aus rendert.
Glortho
1
@glortho Hat dieser Ansatz einen Vorteil gegenüber der Definition des Ereignisses onbeforeunload im new_window? Genauer gesagt, ob dies den Code sofort an das new_window bindet, noch bevor die new_page und ihre Skripte geladen werden?
Khadim Ali
1
@ xiaohan2012 Es gibt einen Hack. Siehe meine Antwort stackoverflow.com/questions/9388380/…
Dustin Hoffner
3
Dies ist keine genaue Methode, um festzustellen, dass das Fenster geschlossen wurde. Die Entlade- und Vorentladeereignisse werden immer dann ausgelöst, wenn das Dokument im Fenster entladen wird, was beispielsweise auf eine Umleitung oder ein erneutes Laden zurückzuführen sein kann. Eine genaue Methode finden Sie in der Antwort von @ DustinHoffner ( stackoverflow.com/a/48240128/51055 ).
Hanf
82

Obwohl die akzeptierte Antwort für denselben Ursprung korrekt ist, habe ich eine Lösung für Popups mit unterschiedlichem Ursprung gefunden:

var win = window.open('http://www.google.com'); 
var timer = setInterval(function() { 
    if(win.closed) {
        clearInterval(timer);
        alert('closed');
    }
}, 1000);

Quelle: atashbahar.com

Für diejenigen, die es in Betracht ziehen.

Sogar Facebook verwendet diesen "Hack" in seinem Javascript SDK .

Sie können dies überprüfen, indem Sie sich den Code ansehen. Suchen Sie einfach nach .closedin https://connect.facebook.net/en_US/sdk.js .

Dustin Hoffner
quelle
3
Schön. Vielen Dank!
Roshana Pitigala
4
Ich glaube nicht, dass dies speziell ein Hack für Cross-Origin ist, es ist tatsächlich der einzig genaue Weg, um zu erkennen, dass das Fenster geschlossen wurde. Die Entlade- und Vorentladeereignisse werden immer dann ausgelöst, wenn das Dokument im Fenster entladen wird. Dies kann auf eine Umleitung oder ein erneutes Laden zurückzuführen sein. Dies bedeutet also nicht unbedingt, dass das Fenster geschlossen wurde.
Hanf
Dies scheint in Microsoft Edge leider nicht zu funktionieren
Jamie McCrindle
Ich habe es gerade auf IE11 - WIN7 getestet: var win = window.open('https://www.google.com/') Wenn der Benutzer Popups zulässt, enthält die winVariable das erwartete Objekt. Natürlich müssen Sie dies mit einem vom Benutzer ausgelösten Ereignis aufrufen. (zB onClickauf etwas)
Dustin Hoffner
13

Der Ereignisname ist onbeforeunloadund nicht onBeforeUnload. JS unterscheidet zwischen Groß- und Kleinschreibung.

Valentinas
quelle
1
Wenn wir Ereignisse anhängen, indem wir es verwenden, wird es als Inline-Eigenschaft an HTML angehängt, und HTML ist inkompatibel, was bedeutet, dass dies absolut keinen Unterschied macht
Nikoss
5

Sie müssen das onbeforeunloadEreignis an das Fenster binden , nachdem es geöffnet wurde.

Der einfachste Weg, dies zu tun, wäre, das Javascript vor dem Herunterladen des Codes im Fensterquellcode zu haben.

Ausführliche Erklärungen finden Sie in diesen beiden sehr ähnlichen Fragen hier und hier zu Stackoverflow.

zufälliger_Benutzername
quelle
Vielen Dank. In der Tat onbeforeunloadund onunloadmuss begrenzt werden, nachdem das untergeordnete Fenster geladen wurde, um korrekt zu funktionieren.
Xavi
0
var new_window = window.open('some_url')

Sie können auch überprüfen, ob dies der Fall new_window.windowist null. Sie müssen es jedoch manuell mit setTimeoutoder setIntervalFunktionen überprüfen .

Dies ist übrigens die einzige Möglichkeit, dies zu überprüfen, wenn Sie sich nicht in derselben Domain befinden.

Petr Odut
quelle
Dies ist nützlich, wenn Sie eine globale Methode haben, die Fenster für Sie öffnet und verwaltet, und die URL je nach Kontext intern oder extern sein kann
jimconte