访问 <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 【问题描述】:我试图找出从父页面访问<iframe>
元素的window
和document
属性的最佳方式。 <iframe>
可以通过 javascript 创建或通过存储在对象属性或变量中的引用访问,因此,如果我理解正确,则排除使用 document.frames
。
我已经看到了很多方法,但我不确定最好的方法。给定一个以这种方式创建的<iframe>
:
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
这样的属性等等。
谁能指出我对这些属性的准确/及时参考,或者简要介绍如何以跨浏览器的方式有效访问<iframe>
的window
和document
属性(没有使用 jQuery 或其他库)?
感谢您的帮助!
【问题讨论】:
【参考方案1】:除 Chrome 之外的所有现代浏览器都支持 iframereference.contentWindow
和 iframereference.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)检查 window
和 document
对象?
我发布的单行解决方案考虑了所有这些因素:)【参考方案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判断一个元素在父窗口还是子窗口内~先谢谢了~