ページ上のどの要素がクリックに反応したかを判断するために必要な Chrome 拡張機能を作成しました。これが私がそれをした方法です:
(1) manifest.json で、「run_at」属性を「document_start」に設定します。(ページの実行を開始する前にスクリプトを挿入する必要があります。)
(2) コンテンツ スクリプトに小さなコードを追加して、スクリプトをページに挿入します。このスクリプトは、EventTarget.prototype.addEventListener をオーバーライドして、動的に割り当てられたクリック リスナーであるすべての要素にフラグを立てます。
let flagClickHandledElements = function() {
let oldEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(event_name, handler_func) {
if (event_name === 'click') {
if (this.setAttribute) {
this.setAttribute('data-has_click_handler', true);
}
}
if (oldEventListener)
oldEventListener(event_name, handler_func);
}
}
function injectScript(func) {
let codeString = '(' + func + ')();';
let script = document.createElement('script');
script.textContent = codeString;
(document.head||document.documentElement).appendChild(script);
}
injectScript(flagClickHandledElements);
(3) manifest.json の "permissions" リストに "webNavigation" を追加します。
(4) バックグラウンド スクリプトにコードを追加して、ページの読み込みが完了したときにコンテンツ スクリプトに通知します。
function onPageDoneLoading(details)
{
chrome.tabs.sendMessage(details.tabId, {"action": "doneloading"});
}
chrome.webNavigation.onCompleted.addListener(onPageDoneLoading);
(5) ページの読み込みが終了したら、コンテンツ スクリプトで、ページ上のすべての要素をスキャンして古いスタイルの「onclick」ハンドラをスキャンする別のスクリプトをページに挿入します。
let gatherOldStyleClickHandledElements = function() {
let all_elements = document.getElementsByTagName("*");
for (let i = 0; i < all_elements.length; i++) {
let el = all_elements[i];
if (el.setAttribute && el.onclick) {
el.setAttribute('data-has_click_handler', true);
}
}
}
function onReceiveMessage(request) {
if (request.action === 'doneloading') {
injectScript(gatherOldStyleClickHandledElements);
} else {
console.log('Unrecognized message');
}
return Promise.resolve("Dummy response to keep the console quiet");
}
(6) 最後に、コンテンツ スクリプト内の要素をテストして、次のようなクリック ハンドラがあるかどうかを確認できます。
if (el.getAttribute('data-has_click_handler'))
console.log('yep, this element has a click handler');