クソアプリアドベントカレンダー2022の12日目の記事です。
Twitterに生え散らかっている草を焼き払えるChrome拡張を作りました。
こんな感じで焼き払えます。
使ってみたい!という方
こちらにコードと使い方を載せています。
解説
メインの仕組みは単純で、 "草" をクリックしたときにGIF画像を表示しているだけです。
全体の流れは、
- bodyへのnodeの追加を監視する
- 追加されたnodeの中のspanタグを取得する
- spanタグの中に "草" という文字が含まれている場合、"草" の部分にクリックイベントを追加
- "草" をクリックしたときに、GIF画像を表示する
- "草" を "灰" に書き換える
という感じです。
要素をいくつかピックアップして具体的に解説していきます。
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拡張は気軽にお遊びツールを作れるのでとてもいいですね。