ブラウザ拡張機能でページの要素を変えたいと思ったときにやること

# 概要

これは[初心者のブラウザ拡張機能 Advent Calendar 2024](https://qiita.com/advent-calendar/2024/browser-extension)の4日目の記事です。

「ブラウザの拡張機能を使ってあるページの要素を変えたいな」と思ったときにどういう手順で調べて変えたら良いのか、ざっくり流れを書いてみます。

# まず知っておいたほうが良いこと

## どんな要素も変えられること

Webページは **Document Object Model（DOM）** というAPIによって操作されます。ブラウザの拡張機能では、このDOMというインターフェイスに接続してWebページを操作するため、たとえば真っ白な画面にしてしまうようなことも可能です。

## HTMLはツリー構造になっていること

HTML文書をブラウザが解釈してWebページとして表示するとき、ブラウザはDOMツリーを作ります。

ある要素を変えるときはツリーのどこを変えているのか意識する必要があります。そうでないと想定外の挙動になったり、なにも変化しなかったりします。

[DOM ツリーとは？](https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model/Using_the_Document_Object_Model#dom_%E3%83%84%E3%83%AA%E3%83%BC%E3%81%A8%E3%81%AF%EF%BC%9F)

## DOMをなんとなく知っておくこと

まとめてしまえば「DOMを知ろう！」ということです。

単純にHTMLのタグやタグのオプションを操作するわけではなく、操作するのはDOM（インターフェイス）です。

そのためDOMとはなにで、どういう役割を担っているのか知りましょう。
Mozillaのサイトがわかりやすく正確です。

[ドキュメントオブジェクトモデル (DOM)](https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model)

# 変えたい要素を調べる方法

## ページから要素を選択する

本題に入ります。
「この要素変えたいな」と思ったらまずはブラウザの開発者ツールを開きます。
`F12キー`、`Ctrl+Shift+I`などで開けます。

開いたら下記画像の赤矢印を選択します。ページから要素を選択する機能です。

![ページから要素を選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302006/139d9001-2ff5-969c-9dd0-a70bd6d3f40b.png)

これを使うとWebページの特定部分を選択して、その要素が何なのか確認できます。
下記画像はQiitaの`いいね`ボタンを調べているときのものです。

![いいねボタン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302006/8ca4dafd-5780-300b-461d-ece3071f4aaf.png)

クリックすると`インスペクター`というタブの該当部分がハイライトされます。
`いいね`ボタンは以下要素であると確認できました。

```html
<button aria-label="いいねする" aria-pressed="false" title="いいねする" disabled="" class="style-10ttvi6"></button>
```

## 要素周辺を確認する

次にその要素周辺の構造を調べます。
さきほどの例で言えば`button`要素の上になにがあるか確認する、ということです。

```html
<div>
  <div>
    <svg>
  </div>
  <button>
</div>
```

Qiitaの`いいね`ボタンは上記のように`div`タグが上にあります。また`button`と同じ階層にも`div`がありました。

もっと上位の階層までさかのぼる場合は`XPath`をコピーします。
右クリックして`コピー`から`XPath`をクリックします。

![XPATH](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302006/b35bb89c-d2bc-fe58-2d48-e647e48644ff.png)

以下のようにルートから現在の要素までの各要素が取得できます。

```text
/html/body/div[1]/div[3]/div/main/section/div[1]/div[1]/button
```

# 要素を変える方法

## querySelector

変えたい要素が見つかったら`document.querySelector`で取得します。

Qiitaの`いいね`ボタンの場合、さきほどの`XPath`を活用して以下のように取得できます。

```Javascript
const b = document.querySelector("body div div div main section div div button")
```

もしくはCSSのクラス名からも取得できます。

```Javascript
const b = document.querySelector("button.style-10ttvi6") 
```

`querySelector`の構文は`タグ名`もしくは`タグ名.クラス名`、`クラス名`です。これらを組み合わせて目的の要素を特定します。

## querySelectorAll

もし変えたい要素が複数ある場合は`querySelectorAll`を使います。
たとえばすべての`p`タグを取得する場合は以下のようにします。

```javascript
const ptags = document.querySelectorAll("p")
```

配列のような形式で取得されるため、それぞれの要素へアクセスするためにForEachを使います

```javascript
const ptags = document.querySelectorAll("p")
ptags.forEach(ptag => {
    // ここで処理
});
```

## styleで要素を変える

`querySelector`もしくは`querySelectorAll`で要素を取得したら、`style`を使って要素を変えます。

たとえば以下は`h1`タグの背景色を赤色にします。

```javascript
const h1tags = document.querySelectorAll("h1");
h1tags.forEach(h1tag => {
    h1tag.style.backgroundColor = "red";
})
```

`style`を更新する場合は`element.style.hogehoge = hugahuga`という形で更新します。

[HTMLElement: style プロパティ](https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/style)