Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What is going on with this article?
@kouchanne

Chrome extensionの content_script と background について

More than 1 year has passed since last update.

ウェブクルー 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さんの「わたし定時で帰ります(仮)」です。
興味深いタイトルですね! よろしくおねがいします!

3
Help us understand the problem. What is going on with this article?
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
kouchanne
サーバーサイドエンジニアをやっています。 AWSよりもGCPのほうが得意です。 Vue.jsの記事が多めです。 GCP,Docker,Java,Scala,Python,Vue.js,TypeScript etc...

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
3
Help us understand the problem. What is going on with this article?