chrome extension について。


ページ内から、contentscripts.js に書いてある
関数を呼び出す方法を教えて下さい。

分かりやすいページを教えて下さっても構いません。


contentscripts.js に下記の様に書き
function hoge(id){ alert(id); }

html内のdivに onclick="hoge('a123')" を追記して
divをクリックしても動作しません。
<div onclick="hoge('a123')">xxxxx</div>

これを、同じ事が出来るように教えて頂けるか、
説明しているページを教えて欲しいのです。

宜しくお願いします。


追記です。

こちらのページを見たのですが、このようにするのが理想でしょうか。
もっと簡単にできる方法はありますでしょうか。
http://d.hatena.ne.jp/IT7C/20151221/1450698892

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2018/07/21 11:23:53
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:a-kuma3 No.2

回答回数4973ベストアンサー獲得回数2154

ポイント300pt

公式ページでは、window.postMessage() を使う例が挙げられています。

ただ、window.postMessage() の説明では、以下のようなことも書かれています。
Window.postMessage() - Web APIs | MDN #Using window.postMessage in extensions

Content scripts should use runtime.sendMessage to communicate with the background script. Web context scripts can use custom events to communicate with content scripts (with randomly generated event names, if needed, to prevent snooping from the guest page).

質問の追記に書かれているはてなダイアリーで紹介されている方法です。

ただ、括弧内に書かれているようにイベントの名前を送る側(Web content script) と受ける側(Content script)で握っておかなければいけないので、先の MDN のサンプルコードのように、送信するデータに決まった目印を入れて、それを受け取る側でチェックをすれば、window.postMessage() とあまり変わらないような気もします。

// page-script.js

var messenger = document.getElementById("from-page-script");

messenger.addEventListener("click", messageContentScript);

function messageContentScript() {
  window.postMessage({
    direction: "from-page-script",
    message: "Message from the page"
  }, "*");
// content-script.js

window.addEventListener("message", function(event) {
  if (event.source == window &&
      event.data &&
      event.data.direction == "from-page-script") {
    alert("Content script received message: \"" + event.data.message + "\"");
  }
});


因みに、Developer.chrome.com のサンプルのように、送り元を特定するなら "type" のような属性名にするのが自然だろうに、何故に "direction" というのは、先の MDN のサンプルコードの末尾にある ”visit the demo page on GitHub” を見ると分かります。
そのサンプルでは、Content script → Web content script への通信も併せて書いてあるからです。

他1件のコメントを見る
id:a-kuma3

汎用的に使いやすくも出来ました。

似たようなことやってました :-)

// content script

const called_from_web_content = {
    hoge: (id, message) => {
        alert(id + " - " + message);
    },
};
window.addEventListener("message", evt => {
    if (evt.source == window &&
        evt.data &&
        evt.data.type == "function.call") {
        if (typeof(called_from_web_content[evt.data.name]) == "function") {
            called_from_web_content[evt.data.name].apply(null, evt.data.param);
        }
    }
});

// page script

function call_content_script_function(name, param) {
    const type = "function.call";
    window.postMessage({type, name, param}, "*");
}

function cs_hoge(id, message) {
    call_content_script_function("hoge", Array.from(arguments));
}

cs_hoge("a-kuma3", "V! V! V! Victory!");

パラメータは何でも渡せるわけじゃないっぽくて、なので Array.from(arguments) なんてふうになってたりします。

2018/07/21 11:25:30
id:worldtravel

なるほど!
現時点では簡単な文字列しか渡していなかったので気が付きませんでした。
ありがとうございます(^^

2018/07/21 11:35:01

その他の回答1件)

id:psne No.1

回答回数605ベストアンサー獲得回数334

ポイント50pt

contentscripts.js からHTML内にタグを挿入することで動作します。

質問の状況を整理すると、

  1. onclick が記述されているHTMLページに
  2. contentscripts.js を挿入したが
  3. 上手く動作しない

と読むことができますが、この認識で良いでしょうか。

拡張機能の仕様として、見かけ上は同じページにスクリプトが挿入されていても互いに干渉することができないため、代替の手段を取る必要があります。

引数を渡したい場合、data属性を利用するなど、いくつかの方法があります。

※参考として、以前サンプルとして用意したはてなブログの一部分に挿入するものもご確認ください。
はてなブログのエディタ画面で何かを表示させるサンプル拡張機能

id:worldtravel

ありがとうございます。
教えて頂いたことと、求めていたことが少々違うようでした。

教えて下さった内容で説明しますと、

injection.js 内に function hoge(id){ alert(id); } と書いておき、

追加した

こんにちは!こんにちは!
に、
onclick属性を追加して
こんにちは!こんにちは!
とし、
これをクリックした際に、injection.js 内に書いた関数でアラートを表示したいと言うことです。

この書き方では動かないのは承知しているので、
どうすれば、同じ事が出来るかを知りたいのです。

実際にはアラートを表示したいわけではないのですが、
関数の呼出方や、引数の渡し方を知りたいと考えております。

宜しくお願い致します。

2018/07/21 09:39:53
id:a-kuma3 No.2

回答回数4973ベストアンサー獲得回数2154ここでベストアンサー

ポイント300pt

公式ページでは、window.postMessage() を使う例が挙げられています。

ただ、window.postMessage() の説明では、以下のようなことも書かれています。
Window.postMessage() - Web APIs | MDN #Using window.postMessage in extensions

Content scripts should use runtime.sendMessage to communicate with the background script. Web context scripts can use custom events to communicate with content scripts (with randomly generated event names, if needed, to prevent snooping from the guest page).

質問の追記に書かれているはてなダイアリーで紹介されている方法です。

ただ、括弧内に書かれているようにイベントの名前を送る側(Web content script) と受ける側(Content script)で握っておかなければいけないので、先の MDN のサンプルコードのように、送信するデータに決まった目印を入れて、それを受け取る側でチェックをすれば、window.postMessage() とあまり変わらないような気もします。

// page-script.js

var messenger = document.getElementById("from-page-script");

messenger.addEventListener("click", messageContentScript);

function messageContentScript() {
  window.postMessage({
    direction: "from-page-script",
    message: "Message from the page"
  }, "*");
// content-script.js

window.addEventListener("message", function(event) {
  if (event.source == window &&
      event.data &&
      event.data.direction == "from-page-script") {
    alert("Content script received message: \"" + event.data.message + "\"");
  }
});


因みに、Developer.chrome.com のサンプルのように、送り元を特定するなら "type" のような属性名にするのが自然だろうに、何故に "direction" というのは、先の MDN のサンプルコードの末尾にある ”visit the demo page on GitHub” を見ると分かります。
そのサンプルでは、Content script → Web content script への通信も併せて書いてあるからです。

他1件のコメントを見る
id:a-kuma3

汎用的に使いやすくも出来ました。

似たようなことやってました :-)

// content script

const called_from_web_content = {
    hoge: (id, message) => {
        alert(id + " - " + message);
    },
};
window.addEventListener("message", evt => {
    if (evt.source == window &&
        evt.data &&
        evt.data.type == "function.call") {
        if (typeof(called_from_web_content[evt.data.name]) == "function") {
            called_from_web_content[evt.data.name].apply(null, evt.data.param);
        }
    }
});

// page script

function call_content_script_function(name, param) {
    const type = "function.call";
    window.postMessage({type, name, param}, "*");
}

function cs_hoge(id, message) {
    call_content_script_function("hoge", Array.from(arguments));
}

cs_hoge("a-kuma3", "V! V! V! Victory!");

パラメータは何でも渡せるわけじゃないっぽくて、なので Array.from(arguments) なんてふうになってたりします。

2018/07/21 11:25:30
id:worldtravel

なるほど!
現時点では簡単な文字列しか渡していなかったので気が付きませんでした。
ありがとうございます(^^

2018/07/21 11:35:01

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません