userscript(Tampermonkey)のメモ
ローカルスクリプトファイルを呼び出す(任意のエディタで開発する)
Tampermonkey上ではローカルスクリプトファイルを読み込み実行するだけにしておけば、スクリプト本体をVSCodeなどの任意のエディタで編集することができる。
また、複数の関数を単一スクリプトにまとめ共通化することで開発効率もあがる。
手順
Tampermonkeyの拡張機能のオプションで「ファイルのURLへのアクセスを許可する」をONにする
Tampermonkeyのダッシュボード>設定>全般>設定のモードを上級者に
設定>セキュリティ>スクリプトによるローカルファイルへのアクセスを許可する を「外部(@requireと@resource)」に変更
スクリプト内で以下のようにする
code:js
// ==UserScript==
// @name hogescript *Rapper*
// @version 0.1
// @description try to take over the world!
// @author You
// @require file://C:/hoge.js //<-- ローカルスクリプトファイルへのパス
// @grant GM_download //<-- grantはここで宣言する
// ==/UserScript==
// 以下空白
あとはC:\hoge.jsにスクリプトの内容を記述する。
書き変わらないエリアを作る(Reactページ対策)
Reactなどで作られているページは、スクリプトによってインタラクティブにほぼ全体が書き換わるので、userscriptで書き換えてもあとから上書きされ無駄になってしまうことが多い。
そういったページはbodyの下に<div id="root">などの、スクリプトが書き換える起点となるノードが置かれていることが多い。
つまりこの#rootよりも上位にノードを新しく挿入してしまえばそれはページスクリプトによって上書きされることはない。
このエリアにボタンなどを置いて、ユーザーが任意のタイミングでスクリプトを発動することができれば便利である。
code:js
//ページ上部に100pxの高さのエリアを作る
const fixedArea = document.createElement("div")
fixedArea.id = "button-area"
fixedArea.style.cssText = "z-index:1000; position:fixed; top:0; width:100%; height:100px; color:white; background-color:black; padding:8px; text-align:center;"
//ボタンを配置
const buttonNode = document.createElement("button")
buttonNode.textContent = "push"
//ボタンが押されたときの挙動
buttonNode.addEventListener("click", () => { alert("pushed") })
fixedArea.appendChild(buttonNode)
//bodyの先頭に表示エリアを挿入
const nBody = document.body
if(nBody.firstChild) {
nBody.insertBefore(fixedArea, nBody.firstChild)
} else {
nBody.appendChild(fixedArea)
}
//本文(body)全体を100pxずらす
nBody.style.marginTop="100px"
画像等をすこしずつダウンロードする
スクリプトのヘッダ部分に// @grant GM_downloadが必要
GM_downloadの挙動はTampermonkeyの上級者設定>ダウンロード BETA>ダウンロードのモード:ネイティブにしておく
「ブラウザーAPI」は拡張の機能を使ってDLする(認証が必要)、「ネイティブ」はそのままDLする
ネイティブの場合拡張子は勝手につけてくれるみたい
ページ内の画像を見つけ次第GM_downloadしていくと大変なことになる(サーバもクライアントも)ので、画像URLを取得したらリスト(配列)に貯めておき、タイマで何秒かごとにダウンロードしていくのがまあ有情かなと
code:js
...
// @grant GM_download
// @grant window.close
// ==/UserScript==
(function() {
'use strict'
//ダウンロードリスト
var urlList = []
//画像URLを取得しリストに格納
for(const item of items) {
urlList.push(item.src)
}
//ダウンロードを1000msごとに呼び出す
var timerId = setInterval(intervalDownload, 1000)
return
function intervalDownload() {
//リストが空なら終了
if(urlList.length == 0) {
clearInterval(timerId)
window.close()
return
}
//リストからひとつ取り出してダウンロード
var url = urlList.pop()
var filename = url.split("?")0.split("/").slice(-1)0 GM_download(url, filename)
//リストの残数をタイトルに表示
document.title = ${urlList.length}
return
}
})();