【问题标题】:Setting focus to iframe contents将焦点设置为 iframe 内容
【发布时间】:2010-09-27 00:14:00
【问题描述】:

我有一个带有document.onkeydown 事件处理程序的页面,我正在将它加载到另一个页面的 iframe 中。我必须在 iframe 内单击才能让内容页面开始“收听”。

有什么方法可以在外部页面中使用 JavaScript 将焦点设置到内部页面,这样我就不必在 iframe 内部单击?

编辑:对评论的回应:

上下文是主窗口是一个类似灯箱的系统,除了不是图片,它显示 iframe,每个 iframe 都是一个带有 keydown/mousemove 处理程序的交互式页面。直到我在显示灯箱后单击 iframe 后,这些处理程序才会触发。

我实际上并不是在寻找传统意义上的“setFocus”,而是“在 iframe contentDocument 上启用事件处理程序”

【问题讨论】:

  • 你能提供更多的上下文吗?您是否在主窗口中输入并期望该文本(以一种或另一种形式)出现在您的 iframe 中?这是相关的,因为在 iframe 中设置焦点会干扰用户在主窗口中输入。

标签: javascript dom iframe setfocus


【解决方案1】:

我在使用 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。

【讨论】:

  • 我猜这是因为 A:iframe 必须完成加载,而 B:safari 有(有?)一个与此相关的错误,需要 setTimeout 至少为 1
  • 感谢分享。效果很好。
  • 设置超时时间很好。我发现 settimeout 解决了很多与事件代码有关的问题......我猜这是因为代码在浏览器事件处理的中间运行,并且 settimeout 将其拉出并在事件全部完成后运行它。跨度>
  • 为什么这里 iframe[0] 被当作数组索引?
【解决方案2】:

使用 contentWindow.focus() 方法,超时可能是等待 iframe 完全加载所必需的。

对我来说,使用属性onload="this.contentWindow.focus()" 也适用于 Firefox,进入 iframe 标签

【讨论】:

  • 将此解决方案与 Jaime 下面的建议结合使用,至少在 mozilla 和 webkit 浏览器中解决了我的问题。仍在检查 IE...
【解决方案3】:
document.getElementsByName("iframe_name")[0].contentWindow.document.body.focus();

【讨论】:

  • 这个解决方案的细微变化在我的项目中起作用。我的版本是:this.iframe[0].contentWindow.document.body.focus(); 但我必须以这种方式修改它才能在我正在使用的插件中工作。
【解决方案4】:

尝试监听父文档中的事件并将事件传递给 iframe 文档中的处理程序。

【讨论】:

    【解决方案5】:

    我有一个类似的问题,我试图专注于从另一个页面加载的 iframe 中的 txt 区域。在大多数情况下它工作。存在一个问题,即当 iFrame 加载但在它可见之前它会在 FF 中触发。所以焦点似乎从未正确设置。

    我用一个类似的解决方案来解决这个问题

        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(); 
    

    【讨论】:

      【解决方案6】:

      我发现 FF 会触发 iframe.contentWindow 的焦点事件,但不会触发 iframe.contentWindow.document。 例如,Chrome 可以处理这两种情况。所以,我只需要将我的事件处理程序绑定到 iframe.contentWindow 以使事情正常进行。 也许这对某人有帮助......

      【讨论】:

        【解决方案7】:

        这是使用 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何时加载的代码改编自BiranchiHow to check if iframe is loaded or it has a content?的回答

        【讨论】:

          【解决方案8】:

          这对我有用,虽然有点不对劲:

          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);
          

          嗯。它还会滚动到内容的底部。猜猜我应该在顶部插入虚拟文本框。

          【讨论】:

            猜你喜欢
            • 2010-12-03
            • 1970-01-01
            • 1970-01-01
            • 2013-05-06
            • 2011-12-28
            • 2010-10-02
            • 1970-01-01
            • 2013-06-14
            • 1970-01-01
            相关资源
            最近更新 更多