简体   繁体   English

下载时打开和关闭新选项卡

[英]Opening and closing a new tab when downloading

On many websites ( Dropbox being a good example), when you click on a document to download it, it opens a new window/tab, then the download prompt appears, and the tab/window immediately closes itself (while the prompt remains open). 在许多网站上( Dropbox就是一个很好的例子),当你点击一个文件进行下载时,它会打开一个新的窗口/标签,然后出现下载提示,并且标签/窗口立即关闭(当提示保持打开状态时) 。

How do I replicate this behavior using javascript? 如何使用javascript复制此行为?

I think one approach would be to detect the appearance of that download prompt, then use window.close() . 我认为一种方法是检测下载提示的外观,然后使用window.close() However, I'm not sure how to detect that particular prompt. 但是,我不确定如何检测该特定提示。

A cross-browser solution is preferred, but anything that'll work in Firefox is greatly appreciated. 首选跨浏览器解决方案,但非常感谢在Firefox中运行的任何内容。

Clarifications 澄清

  1. I'm doing this in a Greasemonkey script 我在Greasemonkey脚本中这样做
  2. The "link" that opens in the new tab is not necessarily a direct link to the document. 在新选项卡中打开的“链接”不一定是文档的直接链接。 Sometimes it is a simple page that starts the download in the background. 有时它是一个简单的页面,在后台启动下载。 I'm referring to the type of sites that have their special "download" page...the ones that say something like "your download will begin shortly, if it doesn't start, please click here". 我指的是那些有特殊“下载”页面的网站类型...那些说“你的下载很快就会开始,如果它没有开始,请点击这里”。

More clarification : With regards to the type of website mentioned in clarification 2 above, what I want to do is click on the download link, have that particular download page load in a new window, and have the window close once the download has been initiated. 更多说明 :关于上面澄清2中提到的网站类型,我想要做的是点击下载链接,在新窗口中加载该特定下载页面,并在下载启动后关闭窗口。

There are three basic parts to what you want: 你想要的有三个基本部分:

  1. You must Intercept the download links. 您必须拦截下载链接。
  2. You must send the link to a new tab when it is clicked, and not just modify it with target="_blank" . 单击时必须将链接发送到新选项卡,而不是仅使用target="_blank"修改。 The tab must be opened with javascript, so that javascript will be allowed to close it when the time comes. 必须使用javascript打开该选项卡,以便在时机成熟时允许javascript关闭它。
  3. Your script must also run-on / handle the "popup" tab, so that it can detect when to close the popup. 您的脚本还必须运行/处理“弹出”选项卡,以便它可以检测何时关闭弹出窗口。

For this discussion, refer to this test page at jsFiddle . 有关此讨论, 请参阅jsFiddle上的此测试页面 It is structured like this: 它的结构如下:

<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>

where the a.dwnPageLink links each open a "Download page" -- which automatically starts a file download after a short delay. 其中a.dwnPageLink链接每个打开一个“下载页面” - 在短暂的延迟后自动启动文件下载。


Intercept the download links ( a.dwnPageLink ): 拦截下载链接( a.dwnPageLink ):

We intercept the links like so: 我们拦截这样的链接:

$("#downloadLinks a.dwnPageLink").each (interceptLink);

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

Note that we also add a CSS class, so that we may quickly see which links have been affected. 请注意,我们还添加了一个CSS类,以便我们可以快速查看哪些链接已受到影响。
openInNewTab will be detailed below. openInNewTab将在下面详述。 It must both open a tab, and it must stop the normal link action. 它必须都打开一个选项卡,它必须停止正常的链接操作。


Send the link to a new tab: 将链接发送到新标签:

We must use window.open() to handle the link. 我们必须使用window.open()来处理链接。 If the page is not opened via window.open , our script will not be able to close it. 如果页面未通过window.open打开,我们的脚本将无法关闭它。

Note that GM_openInTab() cannot be used because it does not cause window.opener to be set properly and otherwise does not provide a mechanism to close the opened tab. 请注意,不能使用GM_openInTab()因为它不会导致正确设置window.opener ,否则不提供关闭打开的选项卡的机制。

The new tab is launched in openInNewTab , which looks like this: 新选项卡在openInNewTabopenInNewTab ,如下所示:

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;
}


Handle the "popup" tab: 处理“弹出”选项卡:

It is not possible to monitor for the File dialog from the launching page. 无法从启动页面监视“文件”对话框。 So we must set the script to also run on the "popup" tab. 因此,我们必须将脚本设置为也在“弹出”选项卡上运行。 Add @include directives accordingly. 相应地添加@include指令。

The popup portion of our script can detect the File dialog by monitoring the beforeunload event. 我们脚本的弹出部分可以通过监视beforeunload事件来检测“文件”对话框。 Browsers will fire the beforeunload event, just before opening the File dialog (and also just before the tab closes, but we can ignore that). 浏览器将在打开“文件”对话框之前触发beforeunload事件(也就在选项卡关闭之前,但我们可以忽略它)。

However, we cannot just close the tab when the dialog appears. 但是,我们不能只在对话框出现时关闭选项卡。 Doing so will close the dialog too. 这样做也会关闭对话框。 So we add a small time delay, and a "Confirm" dialog so that the tab will stay open until the File dialog is closed. 因此,我们添加了一个小的时间延迟和一个“确认”对话框,以便选项卡保持打开状态,直到“文件”对话框关闭。 To clear the Confirm dialog, just hit Enter an extra time (or Click OK ). 要清除“确认”对话框,只需按“输入额外时间”(或单击“ 确定” )。

The code looks like this: 代码如下所示:

$(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
    );
} );


Note: 注意:

  1. Since the script will be running on both "List" pages and "Download" pages, we can tell which is which by checking window.opener . 由于脚本将在“列表”页面和“下载”页面上运行,我们可以通过检查window.opener来判断哪个是哪个。 On a page opened by javascript, this will have a non-null value. 在由javascript打开的页面上,这将具有非null值。
  2. This question did not ask about having the tab load in the background. 这个问题没有询问是否在后台加载了标签。 That can be done, with varying degrees of success, but is a more involved. 这可以做到,取得了不同程度的成功,但更具参与性。 Ask a new question for that. 问一个新问题。


Complete script: 完整的脚本:

This script works on the test page and on CNET / Download pages : 此脚本适用于测试页面CNET /下载页面

// ==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;
}

You can simply do using <a> tag by setting target="_blank" 你可以通过设置target="_blank"来简单地使用<a>标签

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

Demo: http://jsfiddle.net/g5Gn5/ 演示: http//jsfiddle.net/g5Gn5/

It will open a new window/tab and close automatically once file dialog appears. 它将打开一个新窗口/选项卡,并在出现文件对话框后自动关闭。

just use this simple solution : 使用这个简单的解决方案:

<a href="linkToDownloadFile.html" onclick="download('linkToDownloadFile.html'); return false;">

<script>
    function download(link){
      var popout = window.open(link);
      window.setTimeout(function(){
         popout.close();
      }, 2000);
    }
</script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM