web-dev-qa-db-ja.com

iframeコンテンツにフォーカスを設定する

document.onkeydownイベントハンドラを持つページがあり、それを別のページのiframe内にロードしています。コンテンツページで「リスニング」を開始するには、iframe内をクリックする必要があります。

外側のページでJavaScriptを使用して内側のページにフォーカスを設定して、iframe内をクリックする必要がないようにする方法はありますか?

編集:コメントへの応答:

コンテキストは、メインウィンドウがライトボックスのようなシステムであることです。ただし、写真の代わりにiframeが表示され、各iframeはキーダウン/マウスムーブハンドラーを備えたインタラクティブページです。これらのハンドラーは、light-box-thingを表示した後にiframeをクリックするまで起動しません。

実際には、「iframe contentDocumentでイベントハンドラーを有効にする」ほど伝統的な意味で「setFocus」を探しているわけではありません。

40
Jimmy

JQuery Thickbox(ライトボックススタイルのダイアログウィジェット)でも同様の問題がありました。問題を修正した方法は次のとおりです。

function setFocusThickboxIframe() {
    var iframe = $("#TB_iframeContent")[0];
    iframe.contentWindow.focus();
}

$(document).ready(function(){
   $("#id_cmd_open").click(function(){
      /*
         run thickbox code here to open lightbox,
         like tb_show("google this!", "http://www.google.com");
       */
      setTimeout(setFocusThickboxIframe, 100);
      return false;
   });
});

コードはsetTimeout()なしでは機能しないようです。私のテストに基づいて、Firefox3.5、Safari4、Chrome4、IE7、およびIE6で動作します。

55
cheeming

ContentWindow.focus()メソッドを使用すると、おそらくiframeが完全にロードされるのを待つためにタイムアウトが必要になります。

私にとっても、属性onload="this.contentWindow.focus()"を使用すると、Firefoxでiframeタグに機能します。

18
danza
document.getElementsByName("iframe_name")[0].contentWindow.document.body.focus();
6
Jaime Febres

親ドキュメントでイベントをリッスンし、イベントをiframeドキュメントのハンドラーに渡してみてください。

4
Liam

別のページから読み込まれたiframeのtxt領域に焦点を合わせようとしていたときに、同様の問題が発生しました。ほとんどの場合、動作します。 iFrameが読み込まれたときに、表示される前にFFで起動するという問題がありました。そのため、フォーカスが正しく設定されていないようです。

上記のcheemingの答えに対する類似のソリューションでこれを回避しました

    var iframeID = document.getElementById("modalIFrame"); 
//focus the IFRAME element 
$(iframeID).focus(); 
//use JQuery to find the control in the IFRAME and set focus 
$(iframeID).contents().find("#emailTxt").focus(); 
3
nate_weldon

JQueryを使用してiframeを作成し、ドキュメントに追加し、ロードされるまでポーリングしてからフォーカスするコードを次に示します。これは、iframeのロードにかかる時間に応じて動作する場合としない場合がある任意のタイムアウトを設定するよりも優れています。

var jqueryIframe = $('<iframe>', {
    src: "http://example.com"
}),
focusWhenReady = function(){
    var iframe = jqueryIframe[0],
    doc = iframe.contentDocument || iframe.contentWindow.document;
    if (doc.readyState == "complete") {
        iframe.contentWindow.focus();
    } else {
        setTimeout(focusWhenReady, 100)
    }
}
$(document).append(jqueryIframe);
setTimeout(focusWhenReady, 10);

Iframeが読み込まれたことを検出するコードは、- Biranchiiframeが読み込まれたか、コンテンツがあるかどうかを確認する方法

1

FFがiframe.contentWindowのフォーカスイベントをトリガーしますが、iframe.contentWindow.documentのトリガーイベントはトリガーしないことを発見しました。 Chromeは両方のケースを処理できます。したがって、動作させるにはイベントハンドラをiframe.contentWindowにバインドする必要がありました。

1
mile

これは私にとってはうまくいきましたが、少し悪臭がします:

var iframe = ...
var doc = iframe.contentDocument;

var i = doc.createElement('input');
i.style.display = 'none'; 
doc.body.appendChild(i);
i.focus();
doc.body.removeChild(i);

うーん。また、コンテンツの下部までスクロールします。ダミーテキストボックスを上部に挿入する必要があると思います。

0
Jimmy