ventana nueva modal hija flotante emergente con cerrar automaticamente abrir javascript tabs greasemonkey

javascript - modal - Abrir y cerrar una nueva pestaña al descargar



ventana emergente html5 javascript (2)

En muchos sitios web ( Dropbox es un buen ejemplo), cuando hace clic en un documento para descargarlo, abre una nueva ventana / pestaña, luego aparece el mensaje de descarga y la pestaña / ventana se cierra inmediatamente (mientras el mensaje permanezca abierto) .

¿Cómo replico este comportamiento usando javascript?

Creo que un enfoque sería detectar la apariencia de ese aviso de descarga, luego usar window.close() . Sin embargo, no estoy seguro de cómo detectar ese aviso en particular.

Se prefiere una solución de varios navegadores, pero cualquier cosa que funcione en Firefox es muy apreciada.

Aclaraciones

  1. Estoy haciendo esto en un script de Greasemonkey
  2. El "enlace" que se abre en la nueva pestaña no es necesariamente un enlace directo al documento. A veces es una página simple que inicia la descarga en segundo plano. Me refiero al tipo de sitios que tienen su página especial de "descarga" ... los que dicen algo como "su descarga comenzará en breve; si no comienza, haga clic aquí".

Más aclaraciones : con respecto al tipo de sitio web mencionado en la aclaración 2 anterior, lo que quiero hacer es hacer clic en el enlace de descarga, cargar esa página en particular en una nueva ventana y cerrarla una vez que se haya iniciado la descarga. .


Simplemente puede usar la etiqueta <a> configurando target="_blank"

<a href="http://jqueryui.com/resources/download/jquery-ui-1.9.2.custom.zip" target="_blank">Download</a>​

Demostración: http://jsfiddle.net/g5Gn5/

Abrirá una nueva ventana / pestaña y se cerrará automáticamente una vez que aparezca el cuadro de diálogo de archivo.


Hay tres partes básicas para lo que quiere:

  1. Debe interceptar los enlaces de descarga.
  2. Debe enviar el enlace a una nueva pestaña cuando se haga clic en ella, y no solo modificarla con target="_blank" . La pestaña debe abrirse con javascript, para que javascript pueda cerrarla cuando llegue el momento.
  3. La secuencia de comandos también debe ejecutar / controlar la pestaña "emergente" para que pueda detectar cuándo cerrar la ventana emergente.

Para esta discusión, consulte esta página de prueba en jsFiddle . Está estructurado así:

<div id="downloadLinks"> <ul> <li><a class="dwnPageLink" href="http://fiddle.jshell.net/cDTKj/show/"> Test file, download page at jsFiddle </a> </li> <li><a class="dwnPageLink" href="http://dw.com.com/redir..."> TextPad (a great text editor), download page at CNET / Download </a> </li> </ul> </div>

donde cada uno de los enlaces a.dwnPageLink abre una "Página de descarga", que inicia automáticamente la descarga de un archivo después de un breve retraso.


Interceptar los enlaces de descarga ( a.dwnPageLink ):

Nosotros interceptamos los enlaces así:

$("#downloadLinks a.dwnPageLink").each (interceptLink); function interceptLink (index, node) { var jNode = $(node); jNode.click (openInNewTab); jNode.addClass ("intercepted"); }

Tenga en cuenta que también agregamos una clase CSS, para que podamos ver rápidamente qué enlaces se han visto afectados.
openInNewTab se detallará a continuación. Debe abrir una pestaña y debe detener la acción de enlace normal.


Envía el enlace a una nueva pestaña:

Debemos usar window.open() para manejar el enlace. Si la página no se abre mediante window.open , nuestro script no podrá cerrarla.

Tenga en cuenta que GM_openInTab() no se puede usar porque no hace que window.opener se establezca correctamente y de lo contrario no proporciona un mecanismo para cerrar la pestaña abierta.

La nueva pestaña se inicia en openInNewTab , que se ve así:

function openInNewTab (zEvent) { //-- Optionally adjust the href here, if needed. var targURL = this.href; var newTab = window.open (targURL, "_blank"); //--- Stop the link from doing anything else. zEvent.preventDefault (); zEvent.stopPropagation (); return false; }


Maneje la pestaña "emergente":

No es posible controlar el diálogo de Archivo desde la página de inicio. Por lo tanto, debemos configurar el script para que también se ejecute en la pestaña "emergente". Agregue las directivas @include consecuencia.

La parte emergente de nuestra secuencia de comandos puede detectar el cuadro de diálogo Archivo al supervisar el evento beforeunload . Los navegadores activarán el evento antes de la beforeunload , justo antes de abrir el cuadro de diálogo Archivo (y también justo antes de que la pestaña se cierre, pero podemos ignorar eso).

Sin embargo, no podemos cerrar la pestaña cuando aparece el diálogo. Hacerlo también cerrará el diálogo. Así que agregamos un pequeño retraso y un cuadro de diálogo "Confirmar" para que la pestaña permanezca abierta hasta que se cierre el cuadro de diálogo Archivo. Para borrar el cuadro de diálogo Confirmar, solo presione Ingresar un tiempo extra (o haga clic en Aceptar ).

El código se ve así:

$(window).bind ("beforeunload", function (zEvent) { //-- Allow time for the file dialog to actually open. setTimeout ( function () { /*-- Since the time it takes for the user to respond to the File dialog can vary radically, use a confirm to keep the File dialog open long enough for the user to act. */ var doClose = confirm ("Close this window?"); if (doClose) { window.close (); } }, 444 // 0.444 seconds ); } );


Nota:

  1. Como la secuencia de comandos se ejecutará tanto en las páginas "Lista" como en las páginas "Descargar", podemos decir cuál es cuál marcando window.opener . En una página abierta por javascript, esto tendrá un valor no nulo.
  2. Esta pregunta no pedía que la pestaña se cargara en segundo plano. Eso se puede hacer, con diversos grados de éxito, pero es más complicado. Haga una nueva pregunta para eso.


Guión completo:

Esta secuencia de comandos funciona en la página de prueba y en CNET / páginas de descarga :

// ==UserScript== // @name _Download page, auto closer // @namespace _pc // ******** Includes for "List pages" that have the links we might click... // @include http://YOUR_SERVER.COM/YOUR_LIST-PAGE_PATH/* // @include http://jsbin.com/ozofom/* // @include http://fiddle.jshell.net/qy3NP/* // @include http://download.cnet.com/* // ******** Includes for "Popup pages" that do the actual downloads... // @include http://YOUR_SERVER.COM/YOUR_POPUP-PAGE_PATH/* // @include http://fiddle.jshell.net/cDTKj/* // @include http://dw.com.com/redir?* // @require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js // @grant GM_addStyle // @grant GM_openInTab // ==/UserScript== /*- Important: The @include or @match directives must for for both the pages that list the download links, AND the pages that do the actual downloading. The @grant directive is needed to work around a design change introduced in GM 1.0. It restores the sandbox. */ var bPageNotOpenedByJavascript = window.opener ? false : true; if (bPageNotOpenedByJavascript) { /***** "Normal" page, which might contain links to special download pages. */ //--- Intercept links to the download pages: // For our jsFiddle Test page: $("#downloadLinks a.dwnPageLink").each (interceptLink); // For CNET/Download: $("#downloadLinks div.dlLinkWrapper a").each (interceptLink); GM_addStyle ( " / a.intercepted { / background: lime; / } / " ); } else { /***** Page opened by JS in either a popup or new tab. This was *most likely* done by us, using window.open. */ $(window).bind ("beforeunload", function (zEvent) { //-- Allow time for the file dialog to actually open. setTimeout ( function () { /*-- Since the time it takes for the user to respond to the File dialog can vary radically, use a confirm to keep the File dialog open long enough for the user to act. */ var doClose = confirm ("Close this window?"); if (doClose) { window.close (); } }, 444 // 0.444 seconds ); } ); } function interceptLink (index, node) { var jNode = $(node); jNode.click (openInNewTab); jNode.addClass ("intercepted"); } function openInNewTab (zEvent) { //-- Optionally adjust the href here, if needed. var targURL = this.href; var newTab = window.open (targURL, "_blank"); //--- Stop the link from doing anything else. zEvent.preventDefault (); zEvent.stopPropagation (); return false; }