robingho333
@robingho333

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Google Chrome 拡張機能開発における文字列置換の問題について

現在、Google Chromeの拡張機能を練習している者です。開発の過程で困っている点があり、アドバイスをいただければと思い投稿しました。

【問題の概要】
私は現在、Chrome 拡張機能の練習として、ブラウザ上に表示される特定の文字列を変更するプログラムを作成しています。具体的には、content_script.js と manifest.json を使用して、ページ上のテキストを置換するようにしています。しかし、このプログラムを実行すると、テキストは一時的に置換されるものの、すぐに元の表示に戻ってしまいます。

【試したこと】
以下のコードを使用しています。

content_script.js

// content_script.js
function replaceText(node) {
  if (node.nodeType === Node.TEXT_NODE) {
    node.textContent = node.textContent.replace(/ます/g, "でござるよ");
  } else {
    node.childNodes.forEach(replaceText);
  }
}

replaceText(document.body);

manifest.json

{
    "name": "text_replace",
    "description": "text_replace",
    "version": "1.0",
    "manifest_version": 3,
    "action": {
        "default_popup": "popup.html"//練習用に簡単な文字列のみ表示(popuup.htmlは、今回はあまり関係ないかと思っています)。
    },
    "content_scripts": [
        {
          "js": ["content_script.js"],
          "matches": ["https://qiita.com/*"]
        }
    ]
}

【確認できていること】
サイトを読み込んですぐは、「でござるよ」で変更されますが、
スクリーンショット 2024-01-31 134629.png

1秒くらいたつとすぐにもとの「ます」にもどってしまいます。
スクリーンショット 2024-01-31 134645.png

Chromeデベロッパーモードのコンソールで、content_script.jsの中身を打つと、文字列が変更されたまま表示されます。

【質問内容】
この現象が発生する原因として何が考えられるでしょうか?また、この問題を解決するためのアプローチについて、何かヒントをいただけると幸いです。動的なコンテンツの読み込みや、他のJavaScriptの影響などが原因である可能性を考えていますが、具体的な解決策については見つけられていません。

初歩的な質問かもしれませんが、どんな小さなヒントでも大歓迎です。よろしくお願いします。

1

2Answer

原因までは特定していませんがどこかで更新しているのかと思います。
ページ読み込み後に更新すれば変更はされそうですね。

window.onload = function() {
   replaceText(document.body);
}
2Like

Comments

  1. @robingho333

    Questioner

    コメントありがとうございます!
    いただいた旨を反映したところ、無事に解決できました!
    (読み込み時に一瞬、変更される前の文字列が表示されてしまうのは、致し方なしという感じですね)

    修正後のcontent_script.js

    // content_script.js
    function replaceText(node) {
      if (node.nodeType === Node.TEXT_NODE) {
        node.textContent = node.textContent.replace(/ます/g, "でござるよ");
      } else {
        node.childNodes.forEach(replaceText);
      }
    }
    
    window.onload = function() {
       replaceText(document.body);
    }
    

回答ではありませんが、その現象はqiita.comの左カラムだけで起きているようですね。

1Like

Comments

  1. @robingho333

    Questioner

    コメントありがとうございます!
    はい、一部はそのまま表示されているところも残っています。
    左カラムの部分は何かしらで上書きされてしまっているのかと思います。

  2. すでに @local-nm さんが謎を解かれています。
    おそらく左カラムの、ログイン状態によって変わる部分やランキング等は、静的ページのダウンロードが済んだ後、ページに埋め込まれたスクリプトによって動的に新たに生成されるか、もしくは既存の要素が書き換えられるようになっているんだと思います。
    @local-nm さんの提案のように window.onload で置換を実行するようにすれば、そのタイミングならページの動的生成も終わっているので無事置換できるということだと思います。

    なお、左カラム以外の静的な部分は置換できているわけですが、多分コンテンツスクリプトの実行タイミングは明確には規定されていないんじゃないかと思うので、もしサーバーからページを受信している途中(つまり document.body の内容はまだ不完全)なタイミングでコンテンツスクリプトの実行が開始してしまっていたら、その時点でロード済みのテキストしか置換できないことになりますので、いずれにしてもロードが完了するのを待ってから置換を始めるようにしたほうがいいでしょうね。

  3. @robingho333

    Questioner

    コメントと説明いただきありがとうございました!
    無事に問題解決をすることが出来ました。
    何かしらで上書きされてしまっていたので、
    ロード完了を待ってから置換を開始するという動作ですね。
    大変助かりました。

Your answer might help someone💌