将焦点设置为 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 内容的主要内容,如果未能解决你的问题,请参考以下文章