Help us understand the problem. What is going on with this article?

Chrome extensionの content_script と background について

ウェブクルー AdventCalendar 2日目の記事です

2日目@kouchanne が担当します!

1日目と一緒だって?…

書きたいこといっぱいあって書いちゃいました!
どうかお付き合いください。

はじめに

今まで業務で使うchromeのextensionをいくつか自作してきたんですが content_scriptbackground の片方しか使わないシーンしかなく、違いがパットしていなかったのですが最近作ったアプリで点と点がつながる瞬間があったのでそこについて共有できればと思います。

chrome extension

chrome extension とは

この記事を見てくださっている、方はInternetExplorerではなく Googleのchromeかfirefoxの方が多数かと思いますが。
これらには拡張機能があります。※今回はchromeのお話ですがfirefoxも似たようなものがあります
chromeでは拡張機能と呼ばれるウェブブラウジングを便利にしてくれる機能がいっぱいあって、みなさんもお世話になっているかと思います。
公開されているものから使うことが多いと思いますが、実は簡単なjsさえかければ誰でも作れちゃうんです。
※作り方系の記事はいっぱいあるので、今回は初期構築のところはあまり触れません

content_scriptbackground

chrome extension には大きく分けて content_scriptbackground があります。
これらの違いは何かというと

  • content_script ⇒ 閲覧しているページに対して直接操作する。 ブックマークレットをいい感じにしたやつ
  • background ⇒ chromeが起動している裏で仮想のタブが立ち上がっている(見えない)。 ページ関係なくブラウザ側が持つ機能

図で書いてみた

chrome extension.png

  • backgroundから閲覧しているページのDOM要素を直接操作することはできない
  • content_script からchrome側のイベントを検知することができない

そのため、拡張機能のボタンが押されたら閲覧しているサイトの要素を取得していい感じにするみたいなことができない…

content_scriptbackground 間で値のやり取りをしたいときはsendMessageを使うことで実現できます。

実用例

上の部分を抑えたところで実際に以下の作りたいものを叶えるにはどのように実装できるか例を上げてみます。

作りたいもの

chrome 拡張のボタンを押すと、閲覧している対象のページのコンテンツを取得してクリップボードへコピーする

作り方

  1. background側 に ボタンをクリックしたときのイベントトリガーをセットする
  2. イベントトリガー内のfunctionでcontent_script 側にメッセージを飛ばす
  3. content_script側でメッセージを検知したらコンテンツを取得するfunctionを実行する
  4. background側へ取得した値をメッセージで飛ばす
  5. content_script側から渡ってきたメッセージをクリップボードにコピーするfunctionを実行する

ソース

background
// 1 イベントトリガー
chrome.browserAction.onClicked.addListener(function (tab) {
  // 2 メッセージの送信
  chrome.tabs.sendMessage(tab.id, "hogehoge");
});

// 5 メッセージを受け取るトリガー
chrome.runtime.onMessage.addListener(
  function(request,sender,sendResponse){
    console.log("クリップボードにコピーします");
    saveToClipboard(request.body);
    sendResponse("finish");
  }
);

function saveToClipboard(str) {
  var textArea = document.createElement("textarea");
  document.body.appendChild(textArea);
  textArea.value = str;
  textArea.select();
  document.execCommand("copy");
  document.body.removeChild(textArea);
}
content_script
// 3 メッセージを受け取るトリガー
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
  if (request == "hogehoge") {
    var body = copy();
    // 4 取得したコンテンツを値として渡す
    chrome.runtime.sendMessage({body: body},
     function(response){});
  }
});

こんな形で、background で発動したものをcontent_scriptで実行できるようになりました。

さいごに

Chromeの拡張機能はなかなか資料も少なく、初めて触ったときはだいぶ意味がわからなかったですが、
改めてちゃんと実装してみると今回の学びを得ることができ、chrome extension開発でだいぶキーになるポイントだと思ったので共有させていただきました。

chromeはなかなか、商材として扱う機会は少ないですが、業務効率化や個人のちょっとしたツールを作るのには最適なので、作るときのちょっとした参考になればと思います。

明日のアドベントカレンダーは@piwiさんの「わたし定時で帰ります(仮)」です。
興味深いタイトルですね! よろしくおねがいします!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした