必要なものには、次の 3 つの基本的な部分があります。
- ダウンロード リンクをインターセプトする必要があります。
- でリンクを変更するだけでなく、クリックされたときに新しいタブにリンクを送信する必要があります
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、余分な時間を押します (または [ OK ] をクリックします)。
コードは次のようになります。
$(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 によって開かれたページでは、これは null 以外の値になります。
- この質問では、タブをバックグラウンドでロードすることについて尋ねていません。これは、さまざまな程度の成功で実行できますが、より複雑です。そのために新しい質問をしてください。
完全なスクリプト:
このスクリプトは、テスト ページと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;
}