124
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

クソアプリAdvent Calendar 2022

Day 12

Twitterに生えてる草を焼き払えるChrome拡張

Last updated at Posted at 2022-12-12

クソアプリアドベントカレンダー2022の12日目の記事です。
Twitterに生え散らかっている草を焼き払えるChrome拡張を作りました。
e856fea28a883104522bac7e245d849f.gif
こんな感じで焼き払えます。

使ってみたい!という方

こちらにコードと使い方を載せています。

解説

メインの仕組みは単純で、 "草" をクリックしたときにGIF画像を表示しているだけです。

全体の流れは、

  1. bodyへのnodeの追加を監視する
  2. 追加されたnodeの中のspanタグを取得する
  3. spanタグの中に "草" という文字が含まれている場合、"草" の部分にクリックイベントを追加
  4. "草" をクリックしたときに、GIF画像を表示する
  5. "草" を "灰" に書き換える

という感じです。

要素をいくつかピックアップして具体的に解説していきます。

nodeの追加を監視

Twitterはツイートのデータを非同期で取得して表示しています。
なので、 "草" という文字列を探すのは、ツイートが読み込まれた後でなければいけません。

それを実現するためにbodyにnodeが追加されたことをMutationObserverを使って監視しています。

// bodyに新しいnodeが追加されたときにonNodeAddedを発火する
const observer = new MutationObserver(onNodeAdded);
observer.observe(document.body, {
  childList: true,
  subtree: true,
});

MutationObserver は変更を検知したときにcallbackに対して MutationList というListを渡します。
この MutationList の扱いが少々ややこしいのですが、ここでは割愛します。調べるといろいろ出てくると思います。

spanタグの中の "草" の部分にだけクリックイベントを追加

spanタグ内に含まれる"草"の文字をspanタグで置換しています。

span.innerHTML = span.innerHTML.replaceAll(
  "",
  '<span class="burn-target">草</span>'
);

これを実行すると、たとえば元々のDOMが

<span>これは草だわ</span>

となっていた場合、以下のように入れ子になります

<span>これは<span class="burn-target"></span>だわ</span>

これで "草" の部分だけ burn-target というclassを付与できました。
あとはこのclassに対してクリックイベントを追加して、GIFを表示する処理を呼ぶだけです。

"草" をクリックしたときにGIF画像を表示する

kusaSpan.addEventListener("click", (event) => {
  // クリックした位置を基準に表示位置を設定する
  const imagePosition = {
    x: event.clientX + window.pageXOffset,
    y: event.clientY + window.pageYOffset,
  };
  // GIFを表示する
  const image = document.createElement("img");
  image.src = chrome.runtime.getURL("kaiju.gif") + "?" + Date.now();
  image.style.position = "absolute";
  image.style.left = imagePosition.x + "px";
  image.style.top = imagePosition.y + "px";
  document.body.appendChild(image);
});

クリックした位置を基準にしてGIFを表示しています。

ポイントはここです。

image.src = chrome.runtime.getURL("kaiju.gif") + "?" + Date.now();

chrome.runtime.getURL()というのがChrome拡張におけるリソースを呼び出すメソッドです。

そして、末尾にタイムスタンプのクエリをつけています。
image.src = chrome.runtime.getURL("kaiju.gif") のように単純にGIFを読み込むだけだと、GIFがブラウザにキャッシュされてしまいます。
キャッシュされた場合、GIFを1度表示したあとに再度表示すると前回の続きから再生されてしまいます。
これだと "草" をクリックしても2度目以降は最初からGIFが再生されません。
そこでタイムスタンプのクエリをつけることでキャッシュされるのを防ぎ、GIFが常に最初から再生されるようにしています。

ソースコード

もう一度載せておきます。
お好きに改変してお使いください。

Chrome拡張は気軽にお遊びツールを作れるのでとてもいいですね。

参考

124
43
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
124
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?