将焦点设置为 iframe 内容

Posted

技术标签:

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

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

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

编辑:对评论的回应:

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

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

【问题讨论】:

你能提供更多的上下文吗?您是否在主窗口中输入并期望该文本(以一种或另一种形式)出现在您的 iframe 中?这是相关的,因为在 iframe 中设置焦点会干扰用户在主窗口中输入。 【参考方案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何时加载的代码改编自Biranchi对How 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);

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

【讨论】:

以上是关于将焦点设置为 iframe 内容的主要内容,如果未能解决你的问题,请参考以下文章

如何将焦点设置在跨域的 iframe 上

将 iframe 设置为远程内容的内容高度

如何将 HTML 内容设置为 iframe

将 iframe 内容高度设置为动态自动调整大小

当我将元素设置为 Angular 6 中可编辑的内容时,如何设置元素的焦点?

如何将 iframe 高度和宽度设置为 100%