【JavaScript】MutationObserverを使用してDOMの変更を監視する
はじめに
この記事ではMutationObserverを使用してYouTubeLiveのコメントを取得する方法を紹介します。
MutationObserverとは?
MutationObserverはDOMの変更を監視することができます。DOMに変更が加えられると、コンストラクタに渡したコールバック関数が呼び出されます。
YouTubeLiveのコメントを取得してみよう!
MutationObserverを使用してYouTubeLiveのチャット欄を監視し、コメントを取得してみましょう。
チュートリアル
Chromeで好きなYouTubeLiveのページを開き、DevelopperToolを開きます。
コンソールに以下のJavaScriptコードを貼り付けます。
// 監視対象の要素
const element = (
document
.querySelector("iframe#chatframe")
.contentDocument
.querySelector("#chat")
.querySelector("#items")
);
// 追加された子要素を取得するためのオプション
const options = {
childList: true,
};
// 要素からメッセージだけを抽出する
const parseMessage = (node) => {
const container = node.querySelector('#message')
const children = [...container.childNodes];
return children.reduce((message, e) => {
if (e.nodeName === 'IMG') {
message += e.getAttribute('shared-tooltip-text') ?? '';
} else if (e.nodeName === '#text') {
message += e.textContent ?? '';
}
return message;
}, '');
};
// 子要素が追加されるたびに実行される
const callback = (mutationsList, _) => {
for(const mutation of mutationsList) {
mutation.addedNodes.forEach(node => {
const message = parseMessage(node);
console.log(message);
});
}
};
const obs = new MutationObserver(callback);
obs.observe(element, options);
実行するとコメントが表示されます!
簡単な解説
監視対象の要素を取得します。今回はYouTubeLiveのチャットを囲んでいる要素を指定しています。
const element = (
document
.querySelector("iframe#chatframe")
.contentDocument
.querySelector("#chat")
.querySelector("#items")
);
MutationObserver.observe()に渡すオプションを定義しています。オプションの一覧はこちらで確認することができます。今回は小要素の追加を検知したいのでchildListをtrueに設定しています。
const options = {
childList: true,
};
チャットの要素からメッセージだけを取得する関数です。メッセージには画像とテキストが混ざっています。なので、画像の場合はidを表示し、テキストの場合はそのテキストを表示するようにしています。
const parseMessage = (node) => {
const container = node.querySelector('#message')
const children = [...container.childNodes];
return children.reduce((message, e) => {
if (e.nodeName === 'IMG') {
message += e.getAttribute('shared-tooltip-text') ?? '';
} else if (e.nodeName === '#text') {
message += e.textContent ?? '';
}
return message;
}, '');
};
MutationObserverに渡すcallback関数を定義しています。オプションでchildListをtrueに設定したので、子要素が追加された時と削除されたときに実行されます。MutationRecordの配列が第一引数に渡されるので、MutationRecord.addedNodesで追加された要素だけを取得しています。
const callback = (mutationsList, _) => {
for(const mutation of mutationsList) {
mutation.addedNodes.forEach(node => {
const message = parseMessage(node);
console.log(message);
});
}
};
MutationObserverのコンストラクタにcallback関数を渡し、インスタンス化しています。observe関数を実行することで監視が開始されます。
const obs = new MutationObserver(callback);
obs.observe(element, options);
おわりに
この記事では、MutationObserverを使用してDOMの変更を監視する方法を、YouTubeLiveのコメントを取得する例を通して解説しました。今回使用したコードを基にYouTubeLiveのコメントを取得するツールを公開しています。
最後まで読んでいただきましてありがとうございました。
Discussion