14

在许多网站上(Dropbox就是一个很好的例子),当您单击一个文档进行下载时,它会打开一个新窗口/选项卡,然后出现下载提示,并且该选项卡/窗口会立即自行关闭(同时提示保持打开状态) .

如何使用 javascript 复制这种行为?

我认为一种方法是检测该下载提示的外观,然后使用window.close(). 但是,我不确定如何检测该特定提示。

跨浏览器解决方案是首选,但任何可以在 Firefox 中工作的东西都非常感谢。

澄清

  1. 我在 Greasemonkey 脚本中执行此操作
  2. 在新选项卡中打开的“链接”不一定是指向文档的直接链接。有时它是一个简单的页面,在后台开始下载。我指的是具有特殊“下载”页面的网站类型......那些说“您的下载将很快开始,如果没有开始,请点击这里”之类的网站。

更多说明:关于上述说明 2 中提到的网站类型,我要做的是单击下载链接,在新窗口中加载特定的下载页面,并在启动下载后关闭窗口.

4

3 回答 3

12

您想要的内容包含三个基本部分:

  1. 您必须拦截下载链接。
  2. 您必须在单击时将链接发送到新选项卡,而不仅仅是使用target="_blank". 该选项卡必须使用 javascript 打开,以便允许 javascript 在时机成熟时将其关闭。
  3. 您的脚本还必须在“弹出”选项卡上运行/处理,以便它可以检测何时关闭弹出窗口。

有关此讨论,请参阅jsFiddle 上的此测试页面 它的结构是这样的:

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

每个a.dwnPageLink链接都会打开一个“下载页面”——它会在短暂的延迟后自动开始文件下载。


截取下载链接(a.dwnPageLink):

我们像这样拦截链接:

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

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

请注意,我们还添加了一个 CSS 类,以便我们可以快速查看哪些链接受到了影响。
openInNewTab下面会详细介绍。它必须同时打开一个选项卡,并且必须停止正常的链接操作。


将链接发送到新选项卡:

我们必须使用window.open()来处理链接。如果页面不是通过 来打开的window.open,我们的脚本将无法关闭它。

请注意,GM_openInTab()不能使用,因为它不会导致window.opener正确设置,否则不提供关闭打开的选项卡的机制。

新选项卡在 中启动openInNewTab,如下所示:

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


处理“弹出”选项卡:

无法从启动页面监视文件对话框。所以我们必须将脚本设置为也在“弹出”选项卡上运行。相应地添加@include指令。

我们脚本的弹出部分可以通过监视beforeunload事件来检测文件对话框。beforeunload浏览器将在打开“文件”对话框之前触发该事件(以及在选项卡关闭之前,但我们可以忽略它)。

但是,我们不能在对话框出现时关闭选项卡。这样做也会关闭对话框。所以我们添加了一个小的时间延迟和一个“确认”对话框,以便选项卡将保持打开状态,直到文件对话框关闭。要清除“确认”对话框,只需点击Enter额外的时间(或单击“确定” )。

代码如下所示:

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


笔记:

  1. 由于脚本将在“列表”页面和“下载”页面上运行,我们可以通过检查来判断哪个是哪个window.opener。在由 javascript 打开的页面上,这将具有非空值。
  2. 这个问题没有询问在后台加载选项卡。可以做到这一点,取得不同程度的成功,但涉及更多。为此提出一个新问题。


完整脚本:

此脚本适用于测试页面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;
}
于 2012-12-05T11:15:52.927 回答
9

您可以通过设置简单地使用<a>标签target="_blank"

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

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

一旦文件对话框出现,它将打开一个新窗口/选项卡并自动关闭。

于 2012-12-04T03:29:26.797 回答
1

只需使用这个简单的解决方案:

<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>
于 2018-10-10T13:42:13.150 回答