[Chrome拡張]　Chrome拡張メニューとWebページでやりとりする方法(Content Scriptsを使う)

Chrome拡張画面(manu.html)からWebページにアクセスする方法です。
Webページの情報を取得したり、書き換えたりする方法をご紹介します。

今回は、下記の2つを同時に行います。
・Chrome拡張画面　-> Webページ(Content Scripts)
[[Chrome拡張]　Chrome拡張メニューからページを操作する方法](https://qiita.com/doran/items/9203789b570632e2456e)
・Webページ(Content Scripts) ->　Chrome拡張画面
[[Chrome拡張]　Webページ(content scripts)からChrome拡張画面へメッセージを送る方法](https://qiita.com/doran/items/faf21f816b168606cfbe)

:::note info
新しく作成したchrome拡張を公開しました。
そこで使用した技術を備忘録として共有できればと思い、記事を書いています。
[こちらがそのChrome拡張の記事です。ご興味があれば](https://qiita.com/doran/items/8c3ca80de3f149dce0e0)

[こちらは別のChrome拡張の記事です。合わせてどうぞ](https://qiita.com/doran/items/6613ea2d92b330bae2c9)
:::

#### ざっくりとした流れ
menu.jsとscript.jsでメッセージのやりとりを行います。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/40e59d25-8e91-f9c6-7c7c-6cfdbac1d21b.png">

#### 用意するファイル
```
root/
 　├ manifest.json
 　├ menu.html
 　├ js/
 　│　 ├ background.js
 　│　 ├ script.js
 　│　 ├ menu.js
 　│　 └ jquery-3.5.1.min.js
 　└ img/
 　　  ├ icon32.png
  　　 └ icon48.png
```
#### menu.html
button#btnを押すと同じウィンドウで開いている全てのQiita記事の背景を書き換え、
書き換えた記事のタイトルを取得して、div#titleに表示します。
```html
<!DOCTYPE HTML>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title>Webページへ操作テスト2</title>
    <script src="js/jquery-3.5.1.min.js"></script>
    <script src="js/menu.js"></script>
  </head>
  <body>
    <button type="button" id="btn">背景変更＆メッセージ送信</button>
    <div id="title"></div>
  </body>
</html>
```
#### menu.js
menu.htmlのbutton#btnを押したとき、同じウィドウで開かれているQiita記事の背景を
全て書き換え、Qiita記事のタイトル名を取得します。
・Chrome拡張画面　-> Webページ
1.***chrome.tabs.query***
　現在のウィンドウ(***currentWindow***:true)内で、全てのタブを取得します。
2.***chrome.tabs.sendMessage***
　タブに対してメッセージを送信します。
・Webページ　-> Chrome拡張画面
1.***chrome.runtime.onMessage.addListener***
　Webページからのメッセージを受信します。
```js
$(function(){
  $(document).on("click","#btn",function(){
    chrome.tabs.query({currentWindow: true},function(tabs){
      for(let i=0; i<tabs.length; i++){
        //Webページへメッセージを送ります。
        chrome.tabs.sendMessage(tabs[i].id,{"msg":"背景変えて"})
        .then((response)=> { //メッセージ送信が成功した場合
          console.log(response);
        }).catch((error)=> { //メッセージ送信が失敗した場合
          console.log(error);
       });
      }
    });
  });
});
//ページからのメッセージを受け取ります。
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){
  //Qiita記事のタイトル名が送られてくるので、menu.htmlのdiv#title下に追加します。
  $("#title").append($("<div>"+request+"</div>"));
});
```
#### manifest.json
***permissions***は不要です。
***content_scripts***
　matches：　JSを埋め込むページのURLパターンを指定します。
　js：　Webページで実行するJSを指定します。

```json
{
  "name": "Webページ操作テスト2",
  "version": "1.00",
  "description": "Webページ操作テスト2",
  "permissions": [],
  "background": {
    "service_worker": "js/background.js"
  },
  "action": {
    "default_icon": {
      "32": "images/icon32.png"
    }
  },
  "icons": {
    "48": "images/icon48.png"
  },
  "content_scripts": [
    {
      "matches": ["https://qiita.com/doran/items/*"],
      "js": ["js/jquery-3.5.1.min.js","js/script.js"]
    }
  ],
  "manifest_version": 3
}
```
#### background.js
Chromeブラウザのツールバーにあるアイコンがクリック時に「menu.html」を
新しいタブで開くためにbackgroundを用意します。
```js
chrome.action.onClicked.addListener(function(){
  chrome.tabs.create({"url": "menu.html"});
});
```
#### script.js
Webページで実行されるscript.jsを用意します。
manifest.jsonの***content_scripts - matches***で指定した
「https\://qiita.com/doran/items/*」と一致するページのみに埋め込まれます。
```js
//Chrome拡張メニューからメッセージを受け取ります。
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
	if(request.msg=="背景変えて"){	//「背景変えて」とお願いされた
		//メッセージ対しての結果を設定します。
		sendResponse("OK");

		//Qiita記事の背景色を変えています
		$("div.style-yhx9lg").css("backgroundColor","#fbb");
		//Qiita記事のタイトルをChrome拡張メニューへ送信します。
		chrome.runtime.sendMessage($("div.style-yhx9lg h1").text());
	}
});
```
#### 実行結果
1.まずはQiita記事をいくつか開いて
<img width="220" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/3ba4db71-9fd8-e9c8-8579-060dafe7f427.png"><img width="220" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/3eaad308-fd4b-e640-623d-d92074c55921.png"><img width="220" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/7b42a1b1-2be0-5af8-0f48-dcb2e64c22f6.png">
2.Chrome拡張メニューの「背景変更＆メッセージ送信」ボタンを押すと。。。
<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/22a1876a-9949-8eab-7dad-23d165fadae4.png">
3.開いているタブのQiita記事のタイトルが返信されてきた。
<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/1d792988-dc80-e770-b376-320b5a7effe7.png">
4.そして。。Qiita記事の背景も変わってる！
<img width="220" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/401ceef2-bb00-6b0d-2812-9afb811e948e.png"><img width="220" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/88c23eef-5078-73af-fa3b-64f430daa4fc.png"><img width="220" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/a37551bf-6361-fc3e-bb8c-67e473972348.png">
おしまい。。
#### その他のChrome拡張の実装方法
以下はこれまでに投稿したChrome拡張の記事です。用途に応じてご覧ください。
[[Chrome拡張]　ツールバーのアイコンをクリックしてHTMLページを表示する方法](https://qiita.com/doran/items/743f687eb413c41432e1)
[[Chrome拡張]　Chrome拡張メニューからページを操作する方法](https://qiita.com/doran/items/9203789b570632e2456e)
[[Chrome拡張]　Webページ(content scripts)からChrome拡張画面へメッセージを送る方法](https://qiita.com/doran/items/faf21f816b168606cfbe)
[[Chrome拡張]　Chrome拡張画面でタイマー(定期実行処理)を使用する方法](https://qiita.com/doran/items/c2c5c225691fd423b2e6)
[[Chrome拡張]　Content Scriptsでタイマー(定期実行処理)を使用する方法](https://qiita.com/doran/items/2620b2c8f2ac2c5548b6)
[[Chrome拡張]　Chrome拡張メニューからWebページを操作する方法](https://qiita.com/doran/items/8045701ba688f50d6295)
[[Chrome拡張]　Chrome拡張メニューからWebページを操作する方法(jQueryを使う)](https://qiita.com/doran/items/817432932bf77c781002)
[[Chrome拡張]　Chrome拡張メニューとWebページでやりとりする方法](https://qiita.com/doran/items/7ccf10bb310ab46478d4)
[[Chrome拡張]　Chrome拡張メニューとWebページでやりとりする方法(Content Scriptsを使う)](https://qiita.com/doran/items/e69ba19cbd2f5049bc97)
[[Chrome拡張]　Chrome拡張メニューから開いていないWebページの情報を取得する方法](https://qiita.com/doran/items/c2d3249c53b97ddeed0d)
[[Chrome拡張]　ポップアップメニューを表示する方法](https://qiita.com/doran/items/6684c939c5dc2b9d091a)
[[Chrome拡張]　ポップアップメニューからWebページを操作する方法](https://qiita.com/doran/items/c34be1c03353a02cd04f)
[[Chrome拡張]　ポップアップメニューからWebページを操作する方法(jQueryを使う)](https://qiita.com/doran/items/6b7181e369cd1be7dfc4)
[[Chrome拡張]　ポップアップメニューからWebページを操作する方法(スタイル変更)](https://qiita.com/doran/items/00ea4f88862031811ed4)
[[Chrome拡張]　ストレージ(chrome.storage.local)を利用する方法](https://qiita.com/doran/items/38a89bcaf4b89c758725)
[[Chrome拡張]　オプションページを表示する方法](https://qiita.com/doran/items/8154f96c200b73bb9e38)