🍆
JavaScriptで要素の出現を監視する
php-webdriverのuntilとWebDriverExpectedConditionを組み合わせて動的要素の出現を監視して処理を行うみたいなことを、Google Chrome拡張機能でやりたくて力技で関数を用意しました。
SPAサイトが増えてるので意外と使える場面はあるかなと思います。
準備する
function scrapingWaitingForTheElement (targetElement, waitingTime = 30) {
return new Promise(function (resolve, reject) {
let timer, timeout;
// タイムアウトを設定(デフォルト: 30秒、この時間までに要素出力を確認できなければエラー扱いになる)
timeout = setTimeout(function () {
clearInterval(timer);
reject(new Error(targetElement + " の取得に失敗しました。"));
}, waitingTime * 1000);
// 250ミリ秒毎にチェックを実行
timer = setInterval(function () {
if (document.querySelectorAll(targetElement).length > 0) {
clearInterval(timer);
clearTimeout(timeout);
resolve();
}
}, 250); // ここを変更すれば監視間隔を調整できます。
});
}
何か細かい条件で監視したいときは、 document.querySelectorAll(targetElement).length > 0
ここの条件を変更すればOKです。
使ってみる
(async function () {
console.log("実行します。");
try {
// #hoge という要素の出力を 最大10秒間 待機する
await scrapingWaitingForTheElement('#hoge', 10);
} catch (e) {
// タイムアウトしたときの処理
console.log(e);
}
// 上の処理が完了したら下の処理が開始される。
console.log("処理が完了しました。");
})();
MutationObserver
というイベントを使用すると良いらしいのですが、親要素に指定する必要があったり、細かい条件を監視するにはイベント多発しすぎてちょっと面倒な気がしたので簡単な監視としては現時点で上記が個人的には使いやすかったです。(MutationObserverはしっかりと使ってはないので妄想で喋ってます。)
特にSPA系サイトでボタンclick()してページ遷移しようとすると大変なので、
この関数で要素の出現を監視してボタンに aタグ を張り直したりURLを引っ張ってwindow.location.hrefでページ遷移させて、 content_scripts を動かすようにすると楽できます。キレイな動きじゃないですが、個人利用程度には十分です。
安定的かつ超リアルタイムで検出できるようなスマートな書き方あれば教えてください😣
Discussion