質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Chrome

Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Chrome extension

Chrome拡張機能

Q&A

解決済

1回答

3357閲覧

Chrome拡張機能のjavascriptでclassが取得できない

Suisoniumu

総合スコア14

Chrome

Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Chrome extension

Chrome拡張機能

1グッド

1クリップ

投稿2021/09/17 23:40

編集2021/09/18 08:33

前提・実現したいこと

Chrome拡張機能で、webページ中の特定のclassを持つ部分の削除をしたいです。
そこでgetElementsByClassNameでclassを読み取ったのですが、読み取ったhtmlCollectionを表示させると中身が入っているのにその要素数は0と表示されます。どのように解決したらいいでしょうか。

発生している問題・エラーメッセージ

テキストでうまく表示できないので画像にします。
画像中のcontent1.jsが自分の作ったコードの結果になります。
イメージ説明

該当のソースコード

javascript

1let elements = document.getElementsByClassName("mhy-article-card"); 2let num = elements.length; 3 4console.log(elements); 5console.log("entered = " + num); 6 7 8for(let i = 0; i < num; i++){//←nunが0だから機能してない 9 console.log(i); 10 console.log(elements[i]); 11}

manifest

1{ 2 "name": "Sample", 3 "version": "1.0.0", 4 "manifest_version": 2, 5 "description": "Sample Chrome Extension", 6 "content_scripts": [{ 7 "matches": ["https://www.hoyolab.com/home*"], 8 "js": [ 9 "content1.js" 10 ] 11 }] 12}

試したこと

querySelectorAllを使てみましたが、同様にうまくいきませんでした。
Array.prototype.slice.call(elements, 0)で配列にした際は、中身が無くなりました。

・追記
window.addEventListener('load', function() { ソースコードの中身 })というようにロードが終わってからコードを実行するようにしたのですが、それでも解決しませんでした。

補足情報(FW/ツールのバージョンなど)

chromeバージョン :93.0.4577.82(Official Build)
拡張機能はchromeのデベロッパーモードの「パッケージ化されていない拡張機能を読み込む」から使用しています。

退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

int32_t

2021/09/18 05:34

「let num = elements.length;」と「let num = elements.length;」の間は、実際に空白行だけですか? なにか別のコードを実行していませんか。
退会済みユーザー

退会済みユーザー

2021/09/18 07:33

`manifest.json` はどうなってますか。 `content_scripts` の対象のスクリプトの `run_at` の値は `document_idle` が望ましいのですが、`document_start` とか DOM 構築前のタイミングになっていませんか?
Suisoniumu

2021/09/18 08:31

>>let num.... の間 ほかのスクリプトは実行してないです
Suisoniumu

2021/09/18 08:35

>>"manifest.jsonはどうなってますか 該当のソースコードに追記しました。 javascriptはwebページの読み込み時に実行されるようになっています
退会済みユーザー

退会済みユーザー

2021/09/18 09:36

指定しなければデフォルトで `document_idle` になるのでタイミングの問題じゃないですね。 こちらでもその記載されたサイトでのみ問題の再現を確認できました。HTMLCollection はページの DOM の変動が動的に反映されるのでサイト側の動作によるのかと。同様のコードを例えば teratail で実行すると問題なく要素がとれますし…………。
Suisoniumu

2021/09/19 04:01

回答であったMutation observerを使うと解決できました。考えていただきありがとうございました。
guest

回答1

0

ベストアンサー

content script の実行時点でそのクラスを持つ要素は描画されていません。

MDN英語版のgetElementsByClassNameに以下の警告があります。

Warning: This is a live HTMLCollection. Changes in the DOM will reflect in the array as the changes occur. If an element selected by this array no longer qualifies for the selector, it will automatically be removed. Be aware of this for iteration purposes.

getElementsByClassName と querySelectorAll で以下のように違いが出ます。

javascript

1elements = document.getElementsByClassName("a") 2elements.length // 5 3 4document.getElementsByClassName("a")[0].remove() 5elements.length // 4 変更が反映されてる

javascript

1elements = document.querySelectorAll(".a") 2elements.length // 5 3 4document.querySelectorAll(".a")[0].remove() 5elements.length // 5 変更が反映されない

おそらく以下のようなことが起きています

  1. content script が走る
  2. console.log(elements.length) した時点で 0
  3. console.log(elements) は空っぽ
  4. .mhy-article-card の要素が作成される
  5. console.log(elements) が変化する

動的に追加された要素を削除するには Mutation observer で DOM の変更を監視しし、
ここでは .mhy-article-card が追加されてから処理を実行します。

投稿2021/09/18 12:15

neko_daisuki

総合スコア2090

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Suisoniumu

2021/09/19 01:52

Mutation observer で document.body全体を監視し、変更があった際に .mhy-article-card を取得することで解決できました! 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問