Chrome Extension の作り方 (その4: Event Page / Background Page)

[Chrome Extension の作り方 \(その1: 3つの世界\) \- Qiita](https://qiita.com/sakaimo/items/416f36db1aa982d8d00c)
[Chrome Extension の作り方 \(その2: Contents Script\) \- Qiita](https://qiita.com/sakaimo/items/6b7b464de4bdcad18802)
[Chrome Extension の作り方 \(その3: Browser Action / Page Action\) \- Qiita](https://qiita.com/sakaimo/items/129a785146e5873c42a6)

の続き。

Event Page (Background Page)　について説明します。

# できること

Chromeを起動している間ずっと動いてるスクリプトであり、[Declare Permissions](https://developer.chrome.com/extensions/declare_permissions) に書かれているChromeのAPIをフルに使うことが出来ます。

これはExtensionがインストールされてから(その後はChromeが起動されてから)ずっと、目に見えないところで動いているスクリプトだそうです。

`Event Page` と `Background Page` があるのですが、元々は `Background Page` だけで、これは「Chromeを起動してから終了するまでずっと動き続ける=メモリを使い続ける」ので、そうじゃなくて「呼ばれたときだけ起動する」ようにしたのが `Event Page` です。 → 参考 [Chrome拡張では、Background pages よりも Event pages を使用したほうが良い \- よんちゅBlog](http://yonchu.hatenablog.com/entry/2013/05/09/221030)

使わないときにメモリ使ってるのはもったいないので、これから作るなら `Event Page` 一択なのでは？

この2つの違いは、`manifest.json` の中で 

```json
  "background":{
    "scripts":[
      "background.js"
    ],
    "persistent": false
  }
```


- `persistent` が `false` なら `Event Page`
- `persistent` が `true` なら `Background Page`

(それなのに `background.js` という名前が通例的に？残っていてワタシ的には迷うポイントでした。きっと「バックグラウンドで動いているもの」っていう意味合いなんだと思います。ファイル名は任意なので `background.js` じゃなくて `event.js` に変更しても動きます)

`Content Scripts` では利用できるAPIに制限がありましたが、これを使うと [Declare Permissions](https://developer.chrome.com/extensions/declare_permissions) にあるAPIが全て使えます。

今回は `Event Page` だけを扱います。[Chrome機能拡張のイベントページについて \| OXY NOTES](https://oxynotes.com/?p=8928) に詳しく書かれています。(何度も読んだ)

# Event Page 例

`context menu` (右クリックで表示されるメニュー) での操作をします。

[chrome\.contextMenus \- 公式](https://developer.chrome.com/apps/contextMenus)

## ファイル構成

```:ファイル構成
event_page
  └ event.js
  └ jquery-3.4.0.min.js
  └ manifest.json
```

## manifest.json

```json:manifest.json
{
  "manifest_version": 2,
  "name": "Event Pageの実験",
  "version": "1.0",
  "background": {
    "scripts": ["event.js"],
    "persistent": false
  },
  "permissions": [
    "contextMenus",
    "activeTab"
  ]
}
```

## event.js

↓ちょっと長くなってしまいましたが、ほとんどは「右クリックメニュー」のコードです。

```js:event.js
// 拡張機能がインストールされたときの処理
chrome.runtime.onInstalled.addListener(function(){

  // 親階層のメニューを生成
  const parent_menu = chrome.contextMenus.create({
    type: "normal",
    id: "parent",
    title: "背景色を変えるメニュー"
  });

  //子階層のメニューを親(parent_menu)に追加
  chrome.contextMenus.create({
    id: "red",
    parentId: parent_menu,
    title: "赤色"
  });

  chrome.contextMenus.create({
    id: "blue",
    parentId: parent_menu,
    title: "青色"
  });
});


/**
  * メニューが選択されたときの処理
  * 選択されたアイテムはこちらの関数の引数に入ってくる(今回は item)
  * menuItemIdでmenuのidが文字列で取得できる
  */
chrome.contextMenus.onClicked.addListener(function(item){
  console.log("メニューがクリックされたよ");

  // 選ばれたメニューのidが item.menuItemId で取得できる
  chrome.tabs.executeScript({
    code: "document.body.style.backgroundColor = '" + item.menuItemId + "'"
  });
});
```

`chrome.tabs.executeScript` で javascript を画面に挿入することができます。


## 実行する

chrome://extensions/ を開いて `event_page` フォルダをドラッグ&ドロップしてインストール。

![event.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/466d650a-a7ac-5b2b-3ecd-8e6827045ae9.png)

http://example.com/ にアクセスして右クリックすると、自分が作ったメニューが存在しています。

選択する色によって背景色が変わります。

![event_page.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/5c216ed6-1805-c36f-922a-82fe721fb49e.gif)


## デバッグ

上のコードの

```js
  console.log("メニューがクリックされたよ");
```

の出力先ですが、下記の「バックグラウンドページ」をクリックすると出てきます。


![event2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/983a8fbb-734f-e5b4-f54e-b020f0921801.png)

すでに上の例で `background.js` 内に `console.log` して、それが `バックグラウンド ページ` をクリックしたときの デベロッパーツールに表示されているので、そこにログとして出力されます。



![click.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/fcc4477c-9f02-6b5f-ed0c-f2b6d4151f89.png)


# ここまでで

[その2: Contents Script](https://qiita.com/sakaimo/items/6b7b464de4bdcad18802)
[その3: Browser Action / Page Action](https://qiita.com/sakaimo/items/129a785146e5873c42a6)

と今回の記事で、[その1: 3つの世界](https://qiita.com/sakaimo/items/416f36db1aa982d8d00c)で書いた3つの世界それぞれのスクリプトがわかりました。


次回は異なる世界の間で通信を行う `Message Passing` の例を上げたいと思います。

なぜそんなことが必要になるのか、は

[Message Passing \- Google Chrome](https://developer.chrome.com/extensions/messaging)

から最初の一段落を引用すると

>Since content scripts run in the context of a web page and not the extension, they often need some way of communicating with the rest of the extension. For example, an RSS reader extension might use content scripts to detect the presence of an RSS feed on a page, then notify the background page in order to display a page action icon for that page.

だそうです。


# 連載リンク

[Chrome Extension の作り方 \(その1: 3つの世界\) \- Qiita](https://qiita.com/sakaimo/items/416f36db1aa982d8d00c)
[Chrome Extension の作り方 \(その2: Contents Script\) \- Qiita](https://qiita.com/sakaimo/items/6b7b464de4bdcad18802)
[Chrome Extension の作り方 \(その3: Browser Action / Page Action\) \- Qiita](https://qiita.com/sakaimo/items/129a785146e5873c42a6)
[Chrome Extension の作り方 \(その4: Event Page / Background Page\) \- Qiita](https://qiita.com/sakaimo/items/edd910a770b3d5ba83e3)
[Chrome Extension の作り方 \(最終話: メッセージパッシング\) \- Qiita](https://qiita.com/sakaimo/items/5e41d6b2ad8d7ee04b12)