メールを作成するときにメッセージ本文を入力する、Gmail の大きなボックスについて言及していると思います。
" そうだとすれば;
理由:
Gmail のその編集コントロールは、テキスト コントロール (input または textarea) ではありません。これは、設定によって(または ブラウザーのサポートに応じて)編集可能になる で実装されたWYSIWYGエディターです。<iframe>
document.designMode = "on"
document.body.contentEditable = true
したがって、クリックすると; この場合、クエリの方法で常に正しい要素を取得できるとは限りませんdocument.activeElement
。ラッピング (メイン) ドキュメントの, body
( でさえありません) を取得します。iframe
body
例えば; あなたのコードのこの行で、私は信じています。click
イベント リスナーをメイン ドキュメントに追加します。ただし、ページ内の編集可能な iframeにも追加する必要があります。ページと iframe は異なるdocument
オブジェクトを持っているためです (そして、iframe はそれ自体をアクティブとして設定しません)。だから、あなたは間違っているでしょうdocument.activeElement
。
回避策:
必要なイベント リスナーも iframe に追加します。それらについての通知を受け取りたいので。
// Add mouseup event listener to the main document
document.addEventListener('mouseup', logActiveElement, false);
// Get all the iframes on the main document.
var iframeElems = document.getElementsByTagName('iframe');
// Add mouseup event listener to the document of the iframe elements
for (var i = 0; i < iframeElems.length; ++i) {
addIframeEvent(iframeElems[i], true, 'mouseup', logActiveElement);
}
ヘルパー関数は次のとおりです
(メイン ドキュメントから iframe (ドキュメント) にイベント リスナーを追加する方法と、iframe が現在編集可能かどうかを確認する方法に注目してください)。
// Adds the specified event listener to the iframe element.
function addIframeEvent(iframeElem, editableOnly, eventName, callback) {
// Get the document of the iframe element.
var iframeDocument = iframeElem.contentDocument ||
iframeElem.contentWindow.document;
// Watch for editableOnly argument.
if ( (editableOnly && isDocEditable(iframeDocument)) || !editableOnly) {
// Add the event listener to the document of the iframe element.
iframeDocument.addEventListener(eventName, callback, false);
}
}
// Checks whether the specified document is content-editable or in design mode.
function isDocEditable(doc) {
return ( ('contentEditable' in doc.body) && (doc.body.contentEditable === true) ) ||
('designMode' in doc) && (doc.designMode == "on") );
}
// Handler function
function logActiveElement() {
console.log("Active Element:", document.activeElement);
}
これで、イベント ハンドラーは正しいログactiveElement
をコンソールに記録します。
合併症:
結果として; 既存のコードでのテキストの選択やインスペクションなどは、通常の編集コントロール (input、textarea など) と同じようには機能しません。
例えば; getWordUnderCaret(editor)
関数は(ターゲットの) に存在しない を取得insertionPoint
します。このような選別・検査に。DOM SelectionsとDOM Rangesを切り替える必要があります。テキスト編集コントロールのテキスト選択と範囲の代わりに。editor.
selectionStart
document.body
iframe
注: 使用するテキスト選択/範囲 jQuery ライブラリ ( Rangy ) は、ブラウザー内でこの種の編集可能なコンテンツ (iframe、div など) を処理することを約束します。iframe で (Gmail などで) 試しましたか?
さらに詳しい情報:
- Mozilla Developer Network でactiveElement のドキュメントを参照してください。さらに、「ドキュメント上の選択とフォーカスを混同しないでください。選択がない場合、
activeElement
はページの<body>
です。」
アップデート:
Gmail のテキスト コントロールを確認するには; 私もあなたのサンプルコードで遊んだ。
attachTo: ["existing", "top", "frame"]
PageMod オプションに追加されました。
- PageMod オプションでの値
contentScriptWhen
を'end'
( ではなく
) に変更しました。'ready'
DOM、CSS、JS を含むすべてがロードされていることを確認します。一部のコンテンツは、ページの準備/読み込み時に JS を介して変更される可能性があるため、'end' はその後に実行されます。
- メニュー項目にもセレクター コンテキストを適用しました。アイテムがセレクターコンテキスト中にのみ表示されるようにするため。
Gmail (検索ボックス、チャット ボックスなど) およびその他のサイトでテスト済み。これは機能しているようです。addon builderで実際の例
を参照/テストしてください。

