LoginSignup
7
6

More than 5 years have passed since last update.

画面内に重複しているID名がないか調べるChrome拡張を作りました

Last updated at Posted at 2017-01-25

はじめに

同一画面には重複したID名は設定してはいけません。
常識だとは思いますが複数人でプロジェクトを回していると気付いたら同一ID名が存在していた、なんてことあるかと思います。
人間が目で見て重複しているかどうか判断してもいいですが、部分テンプレートが複数にまたがっていたりすると探すのも大変です。
できあがった画面で調べられたら便利だなという発想から作成を開始しました。

使用イメージ

スクリーンショット 2017-01-25 9.49.15.png

  1. URL欄横のブラウザアイコンをクリックするとサーチを開始
  2. サーチが終わるとアラートで通知
  3. 重複したものはコンソールに表示される

ソースコード

background.js
// backgroundで動くjs
// ブラウザ上部のアイコンをクリックすることで発火し、content.jsの方にメッセージを飛ばす(トリガー)
chrome.browserAction.onClicked.addListener(function(tab) {
  /**
   * 第一引数: タブのID
   * 第二引数: ポストするキーとバリュー
   * 第三引数: コールバック関数(レスポンスが戻ってきた時に実行される)
   */
  chrome.tabs.sendMessage(tab.id, { trigger: "on" },
    function(msg) {
      console.log("background側のconsole:", msg);
    });
});
search_not_unique_id.js
$(function(){
  /**
   * @param object message backgroundからポストされた値
   * オブジェクトになっていてmessage.trigger = 'on'のような形になっている
   * @param sender
   * @sendResponse
   * これらは2つとも宣言してないとsendResponseが最後に返せなかったので設定した
   *
   * backgroundからメッセージが送られてきた時(ブラウザボタンをクリックされた時)に発火する
   */
  chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
    // 意図したbackground.jsからの送信でない場合は弾く
    if(message.trigger !== 'on'){
      return false;
    }

    var ids = [];
    // 画面の全要素に対してループを回す(やや遅い可能性あり)
    $.each($("*"), function(){
      var id = $(this).attr("id");
      if(typeof(id) !== "undefined"){
        // undefined以外の全idを配列に保持
        ids.push(id);
      }
    });

    /**
     * 重複したもののみを検出する
     * @see http://qiita.com/cocottejs/items/7afe6d5f27ee7c36c61f
     */
    var not_unique = ids.filter(function (x, i, self) {
      return self.indexOf(x) === i && i !== self.lastIndexOf(x);
    });

    if(ids.length === 0){
      console.log('重複したID要素はありませんでした');
    } else {
      console.log('重複したID要素: ');
      console.log(not_unique);
    }
    alert('結果はconsoleを確認してください');

    sendResponse('Done');
  });
});

解説

全体処理フロー

  1. background.jsでブラウザアイコンにonClickイベントを設定する
  2. ブラウザアイコンがクリックされるとbackground.jsのイベントが発火
  3. sendMessagecontent_scriptsの方にメッセージを送信
  4. content_scriptsmanifest.jsonに指定されているjsが対象
  5. search_not_unique_id.js内にonMessageイベントを配置、これがメッセージを受信した時に発火する
  6. 中で「現在表示しているページに対して」重複してるIDを検索する
  7. sendResponsesearch_not_unique_id.jsからbackground.jsにレスポンスを返す

browser action

ChromeのURL欄の右横のアイコンの部分のこと
今回はここをクリックすることをトリガーにしたかった

background page

その拡張が裏側で持っている拡張用のページのこと
この拡張の作成時、backgroundの方でIDの検索のメイン処理を行っていて、バックグラウンドのページに対して検索をかけてしまいうまくいかない状態でハマりました
バックグラウンドからフロント側(今表示しているタブ側)にメッセージ送信することでトリガーを実現できました
バックグラウンドのページを見るためには以下の画像のようにすると要素が見える

スクリーンショット 2017-01-25 10.39.10.png

おわりに

やってることはすごくシンプルで、コード自体は一瞬で完成しました。
どちらかというとこれをChrome拡張の形に落とし込むのにやや手間取りました。
browser_action, backgroud pageについて良い勉強になりました!
ブラウザアイコンクリック時にポップアップを出したりするのもこのあたりの応用でいけそうなので、次回はこのあたりを触ってみたい:smile:

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6