

タイトルのようなことをするために下記コードを作成しました。しかし、関数も発火せずエラーも出ません。どうすればbackground.jsからpopup.jsにデータを送ることができますでしょうか。

background.js

[code]

    chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
      chrome.tabs.query({active: true, windowId: chrome.windows.WINDOW_ID_CURRENT}, function(result){
        chrome.tabs.sendMessage(result.shift().id, {
          command: "get_dom"
        },
        function(msg) {
          console.log("result message:", msg);
          $.ajax({
            type:"POST",
            url:"http://localhost:3000",
            data: JSON.stringify({
              text: msg
            }),
            dataType: "json",
            contentType:"application/json; charset=UTF-8",
            crossDomain: true,
            success: function(data){
              console.log(data);
              var popup = chrome.extension.getViews({type: "tab"});
              if(popup.length > 0){
                popup[0].showResult(data);
              }
            }
          })
        });
      });
    });
    
[/code]

popup.js

[code]

    $(document).ready(function(){
      $('#submit').click(function(){
        console.log("cliecked");
        chrome.runtime.sendMessage({
          command: "get_text"
        });
      });
    
      function showResult(data){
        console.log(data);
        console.log("received message");
      }
    
    });
    
[/code]


CC BY-SA 3.0
2015-11-28T12:20:41.967
19411
2016-04-17T07:11:29.633
7232
question
javascript jquery chrome-extension
Chrome extensionでbackground.jsからpopup.jsの関数を呼びたい。


まず、この質問のタイトルにある、

> background.jsからpopup.jsの関数を呼びたい

ということですが、根本的に「Event page（=Background）からPopup
pageへの呼び出しは常にできるわけではない」ということがあります。Popup pageのJavaScript Contextは、Browser
ActionまたはPage
Actionのボタンが押された際に作られるものです。つまり、吹き出し型のポップアップが表示された状態でなければ、popup.jsは読み込まれていない状態ですので。

ただ、上記のコードを見てみると、popup.jsからbackground.js、その後background.jsからpopup.js、という流れのようなので、これはできます。いくつか方法があります。

最初は最も簡単な方法として、「background.jsに定義された関数を直接呼ぶ」という方法があります。以下のような感じです。

**background.js**

[code]

    window.foo = (name) => {
      return "Hello, " + name;
    };
    
[/code]

**popup.js**

[code]

    chrome.runtime.getBackgroundPage(function(bg) {
      let msg = bg.foo("Yoichiro");
      // Do something...
    });
    
[/code]

もしreturnでの即返却ではなく、コールバック関数を渡して非同期的に後で呼ばれるような流れにしたいのであれば、以下のようにすれば良いでしょう。

**background.js**

[code]

    window.foo = (name, callback) => {
      callback("Hello, " + name);
    };
    
[/code]

**popup.js**

[code]

    chrome.runtime.getBackgroundPage(function(bg) {
      bg.foo("Yoichiro", (msg) => {
        // Do something...
      });
    });
    
[/code]

これで、background.js側の処理結果をpopup.js側に返すことができるようになります。

もう一つの方法は、chrome.runtime.sendMesasge()を使う方法です。ご提示いただいたコードで使われていて、おそらくpopup.jsからbackbround.jsへのメッセージ送信は成功していると思います。ではbackground.jsからpopup.jsへ処理結果を返すためにはどうしたら良いかなのですが、onMessageイベントのコールバック関数の第3引数「sendResponse」を以下のように使います。

**background.js**

[code]

    chrome.runtime.onMessage.addListener(
      (msg, sender, sendResponse) => {
        sendResponse("Hello, " + msg.name);
      }
    );
    
[/code]

**popup.js**

[code]

    chrome.runtime.sendMessage({
      name: "Yoichiro"
    }, (msg) => {
      // Do something...
    });
    
[/code]

つまり、sendResponse()関数に渡した値は、sendMessage()に渡したコールバック関数呼び出しに変換され、background.js側で渡した値がそのまま引数として得られる、という動作になります。


CC BY-SA 3.0
2016-01-18T05:04:29.143
21023
2016-01-18T05:04:29.143
531
19411
answer