はじめに
ゴシップサイトブロッカーというGoogle Chrome拡張機能を作成しています。ブロックには今まで別の方法を使っていたのですが、バグを修正するためにMutationObserverを使って書き直すことにしました。
その時にハマったことを書いておきます。
孫要素が稀に取得できない
例えば以下のような構造があるとします。
<html>
<body>
<div>
<a>...</a>
</div>
</body>
</html>
このときに、MutationObserverを作成します。
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
for (const node of mutation.addedNodes) {
// ここでブロック判定
}
});
});
observer.observe(document.documentElement, { childList: true, subtree: true });
問題は「ここでブロック判定」の箇所で、ここで以下のような処理を行っています。
(実際はもっと複雑)
- div要素かどうかをチェック
- 1の場合、a要素があるかどうかをチェック
問題は、ごく稀に(15回に1回くらい)、本来あるはずのa要素が見つかりません。
原因
明確なソースは見つからなかったのですが、
親要素(div)が作成されていても、子要素(a)が存在するのは保証されないんだと思います。
対策
a要素が見つからなかったときには、divにMutationObserverを作成し、
見つかるまで待つことにしました。