Javascript обнаруживает закрытие всплывающего окна, загруженного другим доменом
Я открываю всплывающее окно и привязываю к нему событие onbeforeunload следующим образом:
win = window.open("http://www.google.com", "", "width=300px,height=300px");
win.onbeforeunload = function() {
//do your stuff here
alert("Closed");
};
Если я оставил URL пустым, новое всплывающее окно открывается как "about: blank" в качестве адреса, но когда я его закрою, я вижу предупреждение.
Если я открою его, как вы его видите (с внешним URL-адресом), после его закрытия я больше не вижу предупреждения. Любая идея, почему это происходит?
Ответы
Ответ 1
Как уже упоминалось, такая же политика происхождения предотвращает обнаружение Javascript таких событий. Но есть довольно простое решение, позволяющее обнаружить закрытие таких окон.
Здесь код JS:
var openDialog = function(uri, name, options, closeCallback) {
var win = window.open(uri, name, options);
var interval = window.setInterval(function() {
try {
if (win == null || win.closed) {
window.clearInterval(interval);
closeCallback(win);
}
}
catch (e) {
}
}, 1000);
return win;
};
Что он делает: он создает новое окно с предоставленными параметрами, а затем устанавливает функцию checker с интервалом 1 с. Затем функция проверяет, присутствует ли объект окна и имеет ли его закрытое свойство значение false. Если это не так, это означает, что окно (возможно) закрыто и мы должны запустить обратный вызов функции "closeCallback".
Эта функция должна работать со всеми современными браузерами. Некоторое время назад Opera вызывала ошибки при проверке свойств из окон на других доменах - таким образом, блок try..catch. Но я тестировал его сейчас, и кажется, что он работает нормально.
Мы использовали этот метод для создания всплывающих окон "facebook-style" для сайтов, которые не поддерживают их через SDK (ehem... Twitter... ehem). Это потребовало немного дополнительной работы - мы не могли получить никаких сообщений от самого Twitter, но Oauth перенаправила нас обратно в наш домен, а затем мы смогли поместить некоторые данные в объект всплывающего окна, которые были доступны из открывателя. Затем в закрытой функции обратного вызова мы проанализировали эти данные и представили фактические результаты.
Один из недостатков этого метода заключается в том, что обратный вызов вызывается ПОСЛЕ закрытия окна. Ну, это лучшее, что я смог достичь с помощью политики перекрестных доменов.
Ответ 2
Вы можете прослушивать событие "focus" в открывающемся окне, которое запускается, когда пользователь закрывает всплывающее окно.
Ответ 3
К сожалению, вы пытаетесь установить связь между доменами, что запрещено JavaScript той же политикой происхождения. Вам нужно будет использовать прокси-сервер на стороне сервера или какой-нибудь другой уродливый хак, чтобы обойти его.
Вы можете попробовать создать страницу на своем сайте, которая загружает внешний веб-сайт в iframe. Затем вы можете открыть эту страницу и прислушаться к ее разгрузке.
Ответ 4
Я объединил @ от этого, чтобы установить предел интервала (не хотел используйте setTimeout).
Пример (в Typescript объявлен анонимно, чтобы не потерять ссылку на "this"):
private _callMethodWithInterval = (url: string, callback: function, delay: number, repetitions: number) => {
const newWindow = window.open(url, "WIndowName", null, true);
let x = 0;
let intervalID = window.setInterval(() => {
//stops interval if newWindow closed or doesn't exist
try {
if (newWindow == null || newWindow.closed) {
console.info("window closed - interval cleared")
callback();
window.clearInterval(intervalID);
}
}
catch (e) {
console.error(`newWindow never closed or null - ${e}`)
}
//stops interval after number of intervals
if (++x === repetitions) {
console.info("max intervals reached - interval cleared")
window.clearInterval(intervalID);
}
}, delay)
}//end _callMethodWithInterval