0

我正在尋找一種方法來獲取任何頁面的焦點輸入,以更新其值。識別框架層級結構中的true activeElement

我有一個內容腳本接收該值並檢查activeElement是否爲<input>

挑戰在於主文檔的activeElement是iframe時。我可以在清單中設置all_frames: true,它會找到任何活動的<input>,但我只想設置活動iframe的activeElement的值。

目前我正在通過讓子內容腳本blur()除當前所有activeElements(將處理程序附加到focusin)來解決此問題,但不修改文檔狀態的解決方案會更好。

是否有可能只發送一條消息到主文檔,如果這個人的activeElement是一個iframe,得到frameId(並再試一次)?

我不控制網頁。

回答

0

注入一個新的內容腳本來檢查幀的完整層次結構,包括跨域框架。

主要內容腳本詢問背景/活動頁面如果需要的話:

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!'; 
} 
})(); 

我沒有測試這個,但沒有使用過,看過類似的代碼。

+0

有趣的解決方案..也需要在isInputActive情況下有一個監聽器: 如果'''B'''是'''A'''的子幀並且我們正在搜索input-activeElement在B. B中不會有聽衆提供的代碼。 這意味着我也需要拒絕消息(清理收聽者)。 – ttyridal

+0

和A是主窗口.. 相當複雜,但得到了工作 - 而且我還沒有找到更好的方法=>接受 – ttyridal