您想要的内容包含三个基本部分:
- 您必须拦截下载链接。
- 您必须在单击时将链接发送到新选项卡,而不仅仅是使用
target="_blank"
. 该选项卡必须使用 javascript 打开,以便允许 javascript 在时机成熟时将其关闭。
- 您的脚本还必须在“弹出”选项卡上运行/处理,以便它可以检测何时关闭弹出窗口。
有关此讨论,请参阅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
);
} );
笔记:
- 由于脚本将在“列表”页面和“下载”页面上运行,我们可以通过检查来判断哪个是哪个
window.opener
。在由 javascript 打开的页面上,这将具有非空值。
- 这个问题没有询问在后台加载选项卡。可以做到这一点,取得不同程度的成功,但涉及更多。为此提出一个新问题。
完整脚本:
此脚本适用于测试页面和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;
}