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

时间:2012-12-04 03:18:59

标签: javascript tabs greasemonkey

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

如何使用javascript复制此行为?

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

首选跨浏览器解决方案,但非常感谢在Firefox中运行的所有内容。

澄清

  1. 我在Greasemonkey脚本中执行此操作
  2. 在新标签页中打开的“链接”不一定是指向该文档的直接链接。有时它是一个简单的页面,在后台启动下载。我指的是那些有特殊“下载”页面的网站类型...那些说“你的下载很快就会开始,如果没有开始,请点击这里”。
  3. 更多说明:关于上面说明2中提到的网站类型,我想要做的是点击下载链接,在新窗口中加载该特定下载页面,下载完成后关闭窗口。

3 个答案:

答案 0 :(得分:8)

您想要的有三个基本部分:

  1. 您必须拦截下载链接。
  2. 您必须在点击时将链接发送到新标签页,而不只是使用target="_blank"进行修改。必须使用javascript打开该选项卡,以便在时机成熟时允许javascript关闭它。
  3. 您的脚本还必须运行/处理“弹出”选项卡,以便它可以检测何时关闭弹出窗口。
  4. 对于此讨论,请参阅this test page at 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. 这个问题没有询问是否在背景中加载了标签。这可以做到,取得了不同程度的成功,但更具参与性。问一个新问题。

    3. 完整脚本:

      此脚本适用于the test pageCNET / Download pages

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

答案 1 :(得分:7)

您只需设置<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/

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

答案 2 :(得分:0)

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

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