web-dev-qa-db-ja.com

拡張ページDOMではなくWebページDOMにアクセスする方法は?

私はChrome拡張機能を書いており、popup.htmlファイルでボタンがクリックされるとすぐに、現在のWebページに<div>をオーバーレイしようとしています。

Popup.htmlからdocument.body.insertBeforeメソッドにアクセスすると、現在のWebページではなく、ポップアップの<div>がオーバーレイされます。

WebページのDOMにアクセスするには、background.htmlとpopup.htmlの間でメッセージングを使用する必要がありますか? popup.htmlですべてを実行し、可能であればjQueryも使用したいと思います。

62
Steven

Chrome拡張機能の概要に記載されているとおり:architecture (必読):

拡張機能がWebページと対話する必要がある場合、コンテンツスクリプトが必要です。 コンテンツスクリプトは、ブラウザに読み込まれたページのコンテキストで実行されるJavaScriptです。コンテンツスクリプトは、パッケージ化された拡張機能(その親拡張機能)の一部ではなく、読み込まれたページの一部と考えてください。

BrowserActionポップアップは、ブラウザーツールバーのアイコンをクリックしたときに表示されるページです。これは_chrome-extension://_ URLを持つHTMLページです。したがって、DOMにアクセスすると、ポップアップに影響を与えます。同じことが拡張機能の背景/オプションページにも当てはまります。

WebページDOMにアクセス/操作するには、2つの方法があります:

  1. content script(s) in manifest.jsonを宣言し、 messaging を使用する:

    chrome.tabs.sendMessage() バックグラウンド/ポップアップページから挿入されたコンテンツスクリプトの _chrome.runtime.onMessage_ リスナーへ。これはWebページでアクションを実行し、ドキュメントに従ってsendResponseコールバックを介して結果を転送します(注:数値、文字列、配列、単純なオブジェクトなどのJSONで認識可能なオブジェクトのみがサポートされます。つまり、DOM要素ではなく、クラスではなく関数です。コンテンツスクリプトが拡張ページへの通信を開始する必要がある場合、 chrome.runtime.sendMessage() を使用する必要があります。

  2. または Tabs API を使用してコンテンツスクリプトを挿入します
    chrome.tabs.executeScript(tabId, details, callback)

    • 必須 permissions :_"tabs"_、_"https://www.example.com/*"_
      (または_"<all_urls>"_および_"*://*/*"_、_"http://*/*"_、_"https://*/*"_などのバリアント)

    • 明示的なユーザーアクティベーションの場合のより良い選択は、_"activeTab"_および_"tabs"_の代わりに _"<all_urls>"_ permission を使用することです。 _"<all_urls>"_を使用しますが、はインストール中に警告メッセージを表示しません

    • .executeScript()は、挿入されたコンテンツスクリプト内の最後に評価された式の配列を受け取るコールバック関数で使用できます。タブ内に挿入された各フレームごとに1つの要素。 Chromeは結果に対してJSON.parse()およびJSON.stringify()を内部的に使用するため、サポートされる型をプレーンオブジェクトおよび数値/文字列、配列などの単純な文字列化可能な値に制限しますその。
      したがって、DOM要素、関数、カスタムプロパティ、ゲッター/セッターでは機能しません。必要なデータを手動でマップ/抽出し、単純な配列/オブジェクトに渡す必要があります。

コンテンツスクリプトは、隔離された世界と呼ばれる特別な環境で実行されます。 挿入されたページのDOMにはアクセスできますが、ページによって作成されたJavaScript変数や関数にはアクセスできません。各コンテンツスクリプトは、実行中のページで他のJavaScriptが実行されていないかのように見えます。逆も同様です。ページで実行されているJavaScriptは、関数を呼び出したり、コンテンツスクリプトで定義された変数にアクセスしたりできません。

さらに深く進んで、 ウェブページのJavaScript変数/関数 にアクセスすることもできます。



2番目の方法の例として、ブラウザーアクションがクリックされたときにそのdivを表示しましょう。
browserActionクリックハンドラーで chrome.tabs.executeScript() を使用して、コンテンツスクリプトファイル(または、小さい場合はリテラルコード文字列、そのページのDOMのメソッドのドキュメントを参照してください。

_var someVar = {text: 'test', foo: 1, bar: false};
chrome.tabs.executeScript({
    code: '(' + function(params) {
        document.body.insertAdjacentHTML('beforeend',
            '<div style="all:unset; position:fixed; left:0; top:0; right:0; bottom:0;' +
                'background-color:rgba(0,255,0,0.3)">' + params.text + '</div>'
        );
        return {success: true, html: document.body.innerHTML};
    } + ')(' + JSON.stringify(someVar) + ');'
}, function(results) {
    console.log(results[0]);
});
_

ご覧のとおり、関数コードの自動文字列変換を使用して、挿入されたコードを、構文の強調表示とリントを備えた通常のJavaScriptとして記述できるようにしました。明らかな欠点は、ブラウザーがコードの解析に時間を浪費することですが、通常は1ミリ秒未満であるため無視できます。

104
Mohamed Mansour