访问 <iframe> 元素的窗口和文档的最简洁的跨浏览器方法是啥?

Posted

技术标签:

【中文标题】访问 <iframe> 元素的窗口和文档的最简洁的跨浏览器方法是啥?【英文标题】:What's the most concise cross-browser way to access an <iframe> element's window and document?访问 <iframe> 元素的窗口和文档的最简洁的跨浏览器方法是什么? 【发布时间】:2011-02-26 04:28:46 【问题描述】:

我试图找出从父页面访问&lt;iframe&gt; 元素的windowdocument 属性的最佳方式。 &lt;iframe&gt; 可以通过 javascript 创建或通过存储在对象属性或变量中的引用访问,因此,如果我理解正确,则排除使用 document.frames

我已经看到了很多方法,但我不确定最好的方法。给定一个以这种方式创建的&lt;iframe&gt;

var iframe = document.createElement('iframe');
document.getElementsByTagName('body')[0].appendChild(iframe);

我目前正在使用它来访问document,它似乎在主要浏览器上都可以正常工作:

var doc = iframe.contentWindow || iframe.contentDocument;
if (doc.document) 
  doc = doc.document;

我也看到过这种方法:

var iframe = document.getElementById('my_iframe');

iframe = (iframe.contentWindow) ? iframe.contentWindow :
         (iframe.contentDocument.document) ? iframe.contentDocument.document :
         iframe.contentDocument;

iframe.document.open();
iframe.document.write('Hello World!');
iframe.document.close();

这让我很困惑,因为似乎如果定义了iframe.contentDocument.document,你最终会尝试访问iframe.contentDocument.document.document

还有这个:

var frame_ref = document.getElementsByTagName('iframe')[0];

var iframe_doc = frame_ref.contentWindow ? frame_ref.contentWindow.document :
    frame_ref.contentDocument;

最后,我想我对哪些属性持有哪些属性感到困惑,contentDocument是否等同于document或者是否存在contentDocument.document这样的属性等等。

谁能指出我对这些属性的准确/及时参考,或者简要介绍如何以跨浏览器的方式有效访问&lt;iframe&gt;windowdocument 属性(没有使用 jQuery 或其他库)?

感谢您的帮助!

【问题讨论】:

【参考方案1】:

除 Chrome 之外的所有现代浏览器都支持 iframereference.contentWindowiframereference.contentDocument,但前提是在 iframe 中打开的页面与包含 iframe 的页面位于同一域中。

要包含 Chrome,请使用 var iwin=iframereference.contentWindow, idoc=iwin.document;

.contentDocument是iframe中页面的window.document, 和contentWindow.document 一样,但不是.contentDocument.document

Chrome 可能会在未来的某个版本中包含对.contentDocument 的支持——我希望如此,因为它也是所有其他浏览器查找包含在 Object 元素中的文档的方式,输入 text/html,其中 data 属性是html页面的url。

【讨论】:

谢谢,肯尼贝克!所以,我做了一些测试,牢记您的反馈。实际上看起来 IE(至少 IE 7)是 contentDocument 的落后者; Chrome 似乎支持它。 var win = iframe.contentWindow; var doc = iframe.contentDocument || iframe.contentWindow.document; 是否是一个足够且稳定的跨浏览器(回到 IE 6)检查 windowdocument 对象? 我发布的单行解决方案考虑了所有这些因素:)【参考方案2】:

有一种更简单的方法已经存在了很长时间...使用window.frames 来获取对框架窗口对象的引用。

按名称或 ID:

var iframe_doc = window.frames.my_iframe.document;

或者如果您愿意:

var iframe_doc = window.frames['my_iframe'].document;

或按索引:

var iframe_doc = window.frames[0].document;

window.frames 的良好参考:http://developer.mozilla.org/en/DOM/window.frames

摘录:

window.frames 中的每个项目 伪数组表示窗口 对应于给定的对象 或

【讨论】:

【参考方案3】:

在此期间,我进行了许多测试,最后想出了这个简短但健壮的语法,它适用于我可以测试的所有浏览器:

var doc = iframe.contentDocument ?
iframe.contentDocument : (iframe.contentWindow.document || iframe.document);

编辑: @DaggNabbit 注意到 iframe.contentWindow.document 中的引用错误,如果未设置 iframe.contentWindow,将阻止代码执行,不允许返回 iframe.document。 所以我改进了我的代码:

var doc = iframe.contentDocument ?
    iframe.contentDocument :
    (iframe.contentWindow ? iframe.contentWindow.document : iframe.document);

注意:iframe.document 是 IE5 的解决方法。

【讨论】:

这种情况的最后一部分似乎很可疑。它假设 iframe.contentWindow 通过引用它的属性而存在。如果它不存在,它将抛出一个 ReferenceError,并且|| iframe.document 部分将永远不会执行。即使|| iframe.document 确实执行了,它也可能不会做任何有用的事情(假设iframe 是一个iframe 元素,它不会有document 属性,除非有人把它卡在那里)。显然this would not work in Safari circa 2004。 frames 怎么了? 此外,三元和短路 || 运算符的混合使用使得这不必要地笨拙。除了上面的评论,为什么不写var doc = iframe.contentDocument || iframe.contentWindow.document || iframe.document; 我的观点是 iframe.contentWindow.document || iframe.document 没有用处有两个原因:1,iframe 元素没有 document 属性,以及 2,iframe.contentWindow.document 不应该评估为 false。如果 iframe 有一个 contentWindow 窗口属性,那么它肯定会有一个 document 属性,但是如果它们没有 contentWindow 它会抛出一个 ReferenceError,所以无论如何都不会评估 iframe.document。整个事情可以写成var doc = iframe.contentDocument || iframe.contentWindow.document 您确定iframe.document 在IE5 中工作吗?我找不到它的任何记录,但我确实发现有人说只有 window.frames 可以在那个版本的 IE 中工作,here。 嘿嘿,我也试过四处搜索,但找不到任何东西。即使它确实有效,我也可能会坚持使用自互联网诞生以来无处不在的window.frames【参考方案4】:

我认为这是一种非常简单且跨浏览器的方式

//get document object of IFRAME
if(typeof frame.contentDocument!='undefined') 
    iframeDocument=frame.contentDocument;
 else 
    iframeDocument=frame.document;

//get window object of IFRAME
if(typeof frame.contentWindow!='undefined') 
    iframeWindow=frame.contentWindow;
 else 
    iframeWindow=frame.window;

你可以测试一下

【讨论】:

以上是关于访问 <iframe> 元素的窗口和文档的最简洁的跨浏览器方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

求教编程高手,关于JS判断一个元素在父窗口还是子窗口内~先谢谢了~

如何获取iframe的父窗口的body标签啊

jquery iframe父子框架中的元素访问方法

Java Selenium 操作弹出窗口 & 智能等待页面加载完成 & 处理 Iframe 中的元素

从 iFrame 访问 DOM

如何访问 <frameset><iframe> 中的所有表单? [复制]