0

私は目標を持って、値を更新するためにどのページの入力にも集中する方法を模索しています。フレーム階層内の真のactiveElementを特定する

私は値を受け取り、activeElementが<input>であるかどうかをチェックするコンテンツスクリプトを持っています。

問題は、メイン文書のactiveElementがiframeである場合です。私はall_frames: trueをマニフェストに設定することができます。アクティブなものは<input>ですが、アクティブなiframeのactiveElementの値を設定したいだけです。

現在のところ、子コンテンツスクリプトblur()(現在はハンドラを添付してfocusinにする)以外のすべてのactiveElementsを解決していますが、ドキュメントの状態を変更しない方がよいimhoでしょう。

メイン文書のみにメッセージを送信することはできますか?この1つのactiveElementがiframeの場合は、そのフレームIDを取得して(もう一度やり直してください)?

私はウェブページを制御しません。

答えて

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

関連する問題