w3schools validacion pagina manejo leer funcion formularios example ejemplos ejecutar contenido con cargar carga asincrona archivos archivo antes javascript popup onbeforeunload

validacion - Javascript detecta cierre emergente cargado con otro dominio



manejo de archivos en javascript (4)

Como se mencionó, la misma política de origen evita que Javascript detecte tales eventos. Pero hay una solución bastante simple que le permite detectar el cierre de tales ventanas.

Aquí está el código 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; };

Lo que hace: crea una nueva ventana con los parámetros proporcionados y luego establece la función del verificador con un intervalo de 1s. La función luego verifica si el objeto de la ventana está presente y tiene su propiedad cerrada establecida en falso. Si cualquiera de estos dos no es cierto, esto significa que la ventana está (probablemente) cerrada y deberíamos disparar la devolución de llamada ''closeCallback function''.

Esta función debería funcionar con todos los navegadores modernos. Hace algún tiempo, Opera causó errores al verificar las propiedades de Windows en otros dominios, por lo tanto el bloque try..catch. Pero lo he probado ahora y parece que funciona bastante bien.

Utilizamos esta técnica para crear ventanas emergentes de inicio de sesión ''estilo facebook'' para sitios que no las admiten a través de SDK (ehem ... Twitter ... ehem). Esto requirió un poco de trabajo adicional: no pudimos recibir ningún mensaje de Twitter, pero Oauth nos redirigió a nuestro dominio, y luego pudimos colocar algunos datos en el objeto de la ventana emergente a los que se podía acceder desde el abridor. Luego, en la función de devolución de llamada cerrada, analizamos esos datos y presentamos los resultados reales.

Un inconveniente de este método es que la devolución de llamada se invoca DESPUÉS de que la ventana se haya cerrado. Bueno, esto es lo mejor que pude lograr con las políticas de dominios cruzados implementadas.

Estoy abriendo una ventana emergente y adjuntando un evento onbeforenload como:

win = window.open("http://www.google.com", "", "width=300px,height=300px"); win.onbeforeunload = function() { //do your stuff here alert("Closed"); };

Si dejo la URL vacía, la nueva ventana emergente se abre con "about: blank" como la dirección, pero cuando la cierro, veo la alerta.

Si abro como lo ves (con una URL externa), una vez que está cerrado, ya no puedo ver la alerta. ¿Alguna idea de por qué esto está pasando?


Desafortunadamente, está intentando comunicarse entre dominios, lo que está prohibido por la misma política de origen de JavaScript. Tendrías que usar un proxy del lado del servidor o algún otro truco feo para evitarlo.

Puede intentar crear una página en su sitio que cargue el sitio web externo en un iframe. Luego puedes abrir esa página y escucharla para descargarla.


Puede escuchar el evento ''focus'' de la ventana de apertura que se activa cuando el usuario cierra la ventana emergente.


@ThomasZ''s respuesta de @ThomasZ''s con esta para establecer un límite de intervalo (no quería usar setTimeout).

Ejemplo (en Typescript, declarado de forma anónima para no perder la referencia a "esto"):

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