ドキュメント空間の間違いで動作しないexecuteScript

# はじめに
これは、よくある間違いで、つい、うっかりして、犯しているミスですが、気が付くまでに無駄な時間がデバッグに取られてしまいます。あわせて、<strong>executeScript</strong>を実行しているのですが、デバッガーコンソールにVMxxxxが表示されてなく、あっちこっち探しまわるのですが、みつかりません。これも、わかってみれば簡単なことでしたが、<strong>executeScript</strong>にまつわるいくつかの注意事項をまとめてみました。以下にそのサンプルも掲載しました。

# <strong>executeScript</strong>の利用について
最近は、プラグインの作成でよく使うようになりました。結構便利です。<strong>executeScript</strong>が何であるかは他のドキュメントを参照ください。ここでは、利用における使い方の間違いについて記述したいと思います。
主な利用方法は、外部のwebページ(yahooなど)でそこのDOMにアクセスして、いろいろな情報を取得し、整理して、そのページ上にポップ画面を表示し、その画面にまとめた情報を表示するものです。また、ブログなどにyoutube動画を埋め込むことはよく行いますが、その動画にアクセスして、情報を取得し、同じようにポップアップ画面に表示するものです。これらの処理を行う時に、ドキュメント空間を間違えると<strong>executeScript</strong>が動作しません。





# ドキュメント空間の間違い
先に、実際に使用した<strong>executeScript</strong>の引数についてまとめてみます。
サンプルを以下に示します。

``` background.js
//一部を抜粋
let tabId;
let frm_arr_ = [];
//リスナーを登録すると、以後は、アクションがあるごとにこの処理を実行
//引数は、targetとfilesのオブジェクト
chrome.action.onClicked.addListener(
async (tab) => {
console.log("これは、executeScriptSampleプラグインです。");
//
chrome.scripting.executeScript({
     target: {tabId: tab.id, frameIds: [0]},
     files: ["jquery.js","jquery-ui.js"]
 }).then(() => {
     /*******************************************************************
      *executeScript()を起動します。
      *  
      *******************************************************************/
     console.log("■■■executeScript()を起動します。　" + 0);
     //ここでもexecuteScript()を出す
     try {
         chrome.scripting.executeScript({
             //ターゲットのフレームIdのDOMへアクセス  
             target: {tabId: tab.id, frameIds: [0]},
             args: [],
             //実際に実行するexcuteScriptコード
             //ここで、タイトル他をsaveTitle[]に保存するsaveTitleメッセージを
             //background.jsへ送信
             func: () => {
                    console.log("executeScript Test: "+document.title+"  ");
                    if ($("#pop").length === 0) {
                        let html = "";
                        html += "<div id='pop' style='z-index:9999;padding:13px;overflow:scroll;background-color:lightpink;position:fixed;top:0%;left:50%;width:800px;height:400px;'>\n\<span style='zoom:1.2;display:block;background-color:lightgreen;'>pop画面(search-copy-pasteプラグイン)</span>\n\
                        <button id='reset' style='position:absolute;top:15%;left:79%;zoom:1.1;float:left;'>リセット</button>\n\
                        <div id='mess' style='position:relative;top:5%;'></div>\n\
                        <button id='minus' style='zoom:1.5;position:relative;top:0%;left:50%;background-color:lightyellow'>－</button><button id='plus' style='zoom:1.5;position:relative;top:0%;left:55%;background-color:lightyellow'>＋</button>\n\
                        <iframe id='search_site' style='position:relative;top:10%;zoom:1.0;width:1450px;height:600px;' src='https://www.bing.com/search?q=%E7%81%AB%E9%87%8E%E6%AD%A3%E5%B9%B3'></frame>\n\
                        </div>";
                        $("body").append(html);
                        $("#pop").draggable();
                        $("#mess").html("executeScriptで実行<br>拡張機能ボタンがクリックされました。pop画面を追加しました。<br>ページタイトル:<br><span style='color:blue;font-weight:bold;'>"+document.title+"</span>");
                    }else{          
                        $("#mess").html("executeScriptで実行<br>拡張機能ボタンがクリックされました。pop画面がすでにあります。<br>ページタイトル:<br><span style='color:blue;font-weight:bold;'>"+document.title+"</span>");
                    }
                     $("#mess").css("display","block");
                    //
                    //ここで、登録は? セレクターが存在すること。
                    //
                    $("#reset").off('click');
                    $("#reset").on('click',()=>{
                        //alert("executeScript()で定義したリスナーを実行");
                        $("#mess").css("display","none");
                        $("#reset").off('click');
                        return false;
                        
                    });
                    /*******************************************************************
                    *これは、iframeのbingを拡大、縮小するため、
                    *background.jsへ"updown"メッセージを送信して、bingでexecuteScriptを実行  
                    *******************************************************************/
                    chrome.runtime.sendMessage({type: "updown"}, function (response) {

                    });

}       //end func() executeScript()
});         //end executeScript()
}
catch (e) {
}
});
}    
```
ここで、実際に対象のドキュメントで動作するインジェクションスクリプトは、func:()=>{...........}の....で記述された部分のコードです。
はじめにpop画面をbodyにアペンドして表示します。このbodyのドキュメント空間は親フレームになります。引数の
target: {tabId: tab.id, frameIds: [0]},
を見てみますと、2つ指定しています。一つはアクティブのタブのIdで、もう一つは、親フレームのIdです。[0]は親フレームを示します。この[0]を間違えると親フレームにpop画面は表示できません。
pop画面を表示すると、いくつかのボタンが表示されます。それらのボタンにリスナーを登録することもできます。
ここでは、jquery.js、jquery-ui.jsライブラリーも指定していますので、$(セレクター)オブジェクトのメソッドも使用できます。
この<strong>executeScript</strong>で実際に表示したpop画面を以下に表示します。


![saveTitle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198006/da41b69e-cc39-b687-ea47-27cefca06f01.png)

これは、アメバのブログにpop画面を表示した実際の画面です。－、＋のボタンが表示されていますが、これはまだ未完成です。このボタンでbingの表示を拡大、縮小しようと作成中です。ついでですが、このpop画面で行いたいことは、親ページの文字列を選択しするとbingのサーチでその文字列の検索が行えるようにすることです。
メリットは、別のタブが開かずに同じページで検索結果を表示できることです。
話をもどしますが、<strong>executeScript</strong>の実行ドキュメント空間の指定は、引数のtabIdとframeIdsです。これをまちがえると動作しません。


# VMxxxxxが表されない
この問題は、簡単でした。原因は、<strong>executeScript</strong>のコードにありました。コードの中にconsole.log()が一つもないと、VMxxxがデバッガーコンソールに表示されません。
このVMxxxは<strong>executeScript</strong>のデバッグに必須のものです。そのため、必ず一つでもいいので、console.log()を入れるようにしました。
# プラグインのダウンロード(無料)
使い方
このプラグインをダウンロードして、chromeの拡張機能へインストールします。右上に拡張機能を表示して、クリックするとpop画面が表示されます。任意のwebページで動作します。まだ、テスト段階のため、ご容赦ください。例えば、bingのページでリンクをクリックすると新規タブで表示されます。これは、target='_blank'が指定されているためです。検索は同じpop画面内に結果が表示されます。

[search-copy-pasteプラグイン](https://favorite.tecoyan.net/slim/zip/search-copy-paste.zip)

# 埋め込みyoutube動画に適用した例
最後に、executeScriptを埋め込みyoutube動画に適用したサイトについて説明します。
[ameblojimdoプラグインダウンロード]
(https://favorite.tecoyan.net/slim/zip/ameblojimdo.zip)
複数動画を埋め込んでいます。それらの動画のタイトルをpop画面に表示しています。これもexecuteScriptを用いて表示しています。

以下の画面は、ameblojimdoプラグインを適用した例です。

![jimdoポップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198006/8eadd8df-ccbc-a792-57c5-2385804aa051.png)
[ブログのurl](https://tecoyan-net.jimdofree.com/2024/09/07/%E3%83%86%E3%82%B9%E3%83%88/)

このブログを開いて、ameblojimdoプラグインがインストールしてあれば、ctrlキー+clickで、pop画面が表示されます。
各動画のタイトルをpop画面に集めて表示したものです。動画のドキュメント空間とpop画面のドキュメント空間は別物のため、フレームIdで区別してタイトルを表示しています。

pop画面の表示/非表示について
altKey+clickで非表示します。
ctrlKey+clickで表示します。

# あとがき
<strong>executeScript</strong>は慣れると便利で、使いやすいものです。しかし、ちょっと使い方を間違えると動作せず、原因をつかむまで結構時間を取られることがあります。
上記以外にもまだ、使い方を間違えたことがありますので、追加補正して行きたいと思います。