关于iframe
一. iframe获取父级页面对象
在iframe页面中,
window.parent: 获取父级页面的window对象。
window.frameElement: 获取父级页面对iframe对象的引用,就如在父级页面document.getElementById(iframeId)。其实每个window都有frameElement,当它不被作为iframe引用时,该属性就为null或者undefined。PS:之前没有发现这个用法,很有用。
二. 父级页面获取iframe对象
在父级页面中,
获取window对象:
document.getElementById(iframeId).contentWindow: 获取window对象,虽然不是标准方法,但是所有的浏览器都支持。
document.getElementById(iframeId).contentDocument.parentWindow: 获取window对象,但是没有浏览器支持parentWindow属性,只见《Iframes, onload, and document.domain》提过。
window.frames[iframeName/index]: 获取window对象。
其实很好玩,window.frames[iframeName/index].frameElement == document.getElementById(iframeId),
获取document对象:
document.getElementById(iframeId).contentDocument: 获取document对象,且是W3C的标注方法,但是IE6、7不支持。
document.getElementById(iframeId).contentWindow.document: 获取document对象。
window.frames[iframeName/index].document: 获取document对象。
三. 跨域的限制
对于不同域之间的访问,浏览器都是做了限制,《About Cross-Frame Scripting and Security》。在iframe中,只能设置父级页面的location.href属性,但是不能读取,其他属性则都不能访问。
- window.location.href 可写不可读;
- window.location除href之外的属性 禁止;
- document.location.href 可写不可读;
- document.location除href之外的属性 禁止;
如何突破跨域的限制,是另一个话题。
四. iframe的load事件
根据《Iframes, onload, and document.domain》文章所提,主要有两种方法。
方法一
在iframe的window.onload中触发父级页面定义的方法。这个方法的缺点就是要在iframe页面中增加代码,优点也是显而易见的。这是作者逆向思维的产物。
方法二
var iframe = document.createElement("iframe");
iframe.src = "simpleinner.htm";
if (iframe.attachEvent){
iframe.attachEvent("onload", function(){
alert("Local iframe is now loaded.");
});
} else {
iframe.onload = function(){
alert("Local iframe is now loaded.");
};
}
document.body.appendChild(iframe);
《判断 iframe 是否加载完成的完美方法》中也提到方法二是很完美的,但文中提到“ 因为 readystatechange 事件相对于 load 事件有一些潜在的问题”,一直不明白readystatechange存在什么问题。
在另一篇文章中看到两篇引用。OnReadyStateChange and OnLoad Events Not Fired for an IFrame 和 document.readyState Not in Sync with Download in IFrame。大体是讲iframe不一定触发OnReadyStateChange 和 OnLoad事件,以及readystate与iframe的实际状态并不同步。我想大概是这个原因吧。
主要参考:
Iframes, onload, and document.domain
【翻译】Iframes, onload, and document.domain