web-dev-qa-db-ja.com

Greasemonkey / Tampermonkey / userscriptをiframeに適用しますか?

タイトルはほとんど問題です:

Iframed WebサイトにGreasemonkeyスクリプトを追加することは可能ですか?

もしそうなら、どうですか?

ありがとうございました。

16
UpIX

Greasemonkey(およびTampermonkeyおよびほとんどのuserscriptエンジン)では、スクリプトはiframeで自動的に起動します@ include@ exclude 、および/または @ match ディレクティブ。
そして、よくある質問は Greasemonkeyがiframeで実行されないようにする方法 です。

したがって、スクリプトに次のような一致がある場合:

@match https://fiddle.jshell.net/*

JsFiddleの「出力」ページがiframeに表示されているかどうかに関係なく起動します。


JUST iframedコンテンツで発砲したい場合:

次に、window.selfプロパティ。
たとえば、次のようなターゲットページがあるとします。

<body>
    <h1>I'm some webpage, either same-domain or not.</h1>
    <iframe src="//domain_B.com/somePath/somePage.htm">
...

次に、次のようなスクリプトを使用できます。

// ==UserScript==
// @name    _Fires specially on domain_B.com iframes
// @match   *://domain_B.com/somePath/*
// ==/UserScript==

if (window.top === window.self) {
    //--- Script is on domain_B.com when/if it is the MAIN PAGE.
}
else {
    //--- Script is on domain_B.com when/if it is IN AN IFRAME.
    // DO YOUR STUFF HERE.
}

重要:

Greasemonkey 4のリリースに伴い、iframeの処理が大幅に損なわれます (そして、他にも多くのものが壊れています)。
それまだTampermonkey、Violentmonkeyと適切に動作しますほぼすべての他のユーザースクリプトエンジン。
Greasemonkey 4以降を使用しないことを強くお勧めします( Greasemonkey自体を含む )。

17
Brock Adams

これは、iframeに_@include_または_@match_をトリガーする場所がない場合の解決策です。

これはGreasemonkey 4で動作します

フレームを操作する前に、各フレームが読み込まれるのを待つ必要があります。 _waitForKeyElements.js_ を使用してこれを行います。これは、 document.querySelectorAll("selector") で一致をループするように、指定されたCSSセレクタに一致する要素を待機します。次に、指定された関数を応答に適用します。

_// ==UserScript==
// @include https://blah.example.com/*
// @require https://git.io/waitForKeyElements.js
// ==/UserScript==

function main(where) {
  // do stuff here with  where  instead of  document
  // e.g. use  where.querySelector()  in place of  document.querySelector()
  // and add stylesheets with  where.head.appendChild(stylesheet)
}

main(document); // run it on the top level document (as normal)

waitForKeyElements("iframe, frame", function(elem) {
  elem.removeAttribute("wfke_found"); // cheat wfke's been_there, use our own
  for (let f=0; f < frames.length; f++) {
    if (!frames[f].document.body.getAttribute("been_there")) {

      main(frames[f].document);

      frames[f].document.body.setAttribute("been_there", 1);
    }
  }
});
_

選択した要素は、iframeが読み込まれたことを示す単なるプレースホルダーであることに注意してください。フレームが後で再び読み込まれる可能性があるため、「been there」トラッカーをwaitForKeyElementsから削除します(そのiframeは他の場所に読み込まれるため、単に使用することはできません)。

フレームが読み込まれたことがわかったら、各フレームをループしてマーカー、つまり_been_there_(_<body been_there="1">_など)と呼ばれるフレームのbody内のHTML属性を探します。それがない場合は、フレームのドキュメントに対してmain()関数を実行できます。完了したら、_been_there_属性を追加して、再度トリガーされないようにします。

2
Adam Katz

ユーザースクリプトにchrome拡張機能を作成する場合は、マニフェストに"all_frames": trueを追加する必要があります。そうしないと、拡張機能がiframeで機能しません。

マニフェストファイルの例:

"content_scripts": [
    {
      "matches": ["*://*/*"],
      "all_frames": true,
      "js":["dont.js"],
      "run_at":"document_start"
    }
  ]

使用例: https://github.com/NavinF/dont

1
Navin