注入一個新的內容腳本來檢查幀的完整層次結構,包括跨域框架。
主要內容腳本詢問背景/活動頁面如果需要的話:
if (document.activeElement.matches('input') && window == parent) {
console.log('Input', document.activeElement);
document.activeElement.value += ' gotcha!';
} else {
chrome.runtime.sendMessage({action: 'modifyInput'});
}
background/event page腳本在所有幀執行額外的內容腳本:
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse)) {
if (msg.action == 'modifyInput') {
chrome.tabs.executeScript(sender.tab && sender.tab.id, {
file: 'modify-input.js',
allFrames: true,
matchAboutBlank: true,
runAt: 'document_end',
});
}
});
修改輸入。 js,IIFE用於確保垃圾收集刪除注入的東西。
;(function() {
if (isInputActive()) {
if (window == parent) {
foundTheInput();
} else {
askParent();
}
} else if (isFrameActive()) {
window.addEventListener('message', function onMessage(e) {
if (!e.data || e.data.id != chrome.runtime.id)
return;
switch (e.data.action) {
// request from a child frame
case 'checkme':
if (window == parent) {
confirmChild(e.source);
window.removeEventListener('message', onMessage);
} else {
askParent();
}
break;
// response from a parent
case 'confirmed':
window.removeEventListener('message', onMessage);
if (isInputActive()) {
foundTheInput();
} else if (isFrameActive()) {
confirmChild(e.source);
}
break;
}
});
}
function isInputActive() {
return document.activeElement.matches('input');
}
function isFrameActive() {
return document.activeElement.matches('frame, iframe');
}
function askParent() {
parent.postMessage({id: chrome.runtime.id, action: 'checkme'}, '*');
}
function confirmChild(childWindow) {
console.log('Frame', document.activeElement);
childWindow.postMessage({id: chrome.runtime.id, action: 'confirmed': true}, '*');
}
function foundTheInput() {
console.log('Input', document.activeElement);
document.activeElement.value += ' gotcha!';
}
})();
我沒有測試這個,但沒有使用過,看過類似的代碼。
有趣的解決方案..也需要在isInputActive情況下有一個監聽器: 如果'''B'''是'''A'''的子幀並且我們正在搜索input-activeElement在B. B中不會有聽衆提供的代碼。 這意味着我也需要拒絕消息(清理收聽者)。 – ttyridal
和A是主窗口.. 相當複雜,但得到了工作 - 而且我還沒有找到更好的方法=>接受 – ttyridal