基本上,我在页面中嵌入了一个iframe,该iframe有一些需要从父页面调用的JavaScript例程。
现在相反的是相当简单,因为你只需要调用parent.functionName(),但不幸的是,我需要的恰恰相反。
请注意,我的问题不是改变iframe的源URL,而是调用iframe中定义的函数。
基本上,我在页面中嵌入了一个iframe,该iframe有一些需要从父页面调用的JavaScript例程。
现在相反的是相当简单,因为你只需要调用parent.functionName(),但不幸的是,我需要的恰恰相反。
请注意,我的问题不是改变iframe的源URL,而是调用iframe中定义的函数。
当前回答
为了记录,我今天遇到了同样的问题,但这次页面嵌入在对象中,而不是iframe(因为它是XHTML 1.1文档)。下面是它如何处理对象:
document
.getElementById('targetFrame')
.contentDocument
.defaultView
.targetFunction();
(对不起,很难看的换行,不适合单行)
其他回答
quirkmode在这方面有一篇文章。
由于这个页面现在已经坏了,只能通过archive.org访问,我在这里复制了它:
IFrames
在本页中,我简要介绍了如何从iframe所在的页面访问它们。毫无疑问,这里有一些浏览器方面的考虑。
iframe是一种内联框架,这种框架虽然包含一个具有自己URL的完全独立的页面,但仍然放置在另一个HTML页面中。这为网页设计提供了很好的可能性。问题是如何访问iframe,例如在其中加载一个新页面。本页解释了如何做到这一点。
框架还是物体?
最基本的问题是iframe是被视为一个框架还是一个对象。
As explained on the Introduction to frames pages, if you use frames the browser creates a frame hierarchy for you (top.frames[1].frames[2] and such). Does the iframe fit into this frame hierarchy? Or does the browser see an iframe as just another object, an object that happens to have a src property? In that case we have to use a standard DOM call (like document.getElementById('theiframe')) to access it. In general browsers allow both views on 'real' (hard-coded) iframes, but generated iframes cannot be accessed as frames.
名称属性
最重要的规则是给您创建的任何iframe一个name属性,即使您还使用id。
<iframe src="iframe_page1.html"
id="testiframe"
name="testiframe"></iframe>
大多数浏览器需要name属性使iframe成为框架层次结构的一部分。一些浏览器(特别是Mozilla)需要id来将iframe作为对象访问。通过将这两个属性都分配给iframe,您可以保持选择的开放性。但名字远比身份重要。
访问
你可以将iframe作为对象访问并改变它的src,也可以将iframe作为框架访问并改变它的location.href。
. getelementbyid(“iframe_id”)。SRC = 'newpage.html'; 帧的iframe_name .location。Href = 'newpage.html'; 框架语法稍好一些,因为Opera 6支持它,但不支持对象语法。
访问iframe
因此,为了获得完整的跨浏览器体验,您应该为iframe命名并使用
frames['testiframe'].location.href
语法。据我所知,这总是管用的。
访问文档
如果使用name属性,则在iframe中访问文档非常简单。若要在iframe中计算文档中的链接数量,请执行 帧的testiframe .document.links.length。
生成的iframes
当你通过W3C DOM生成一个iframe时,iframe不会立即被输入到frames数组中,而frames[' testframe '].location。Href语法将不能立即工作。在iframe出现在数组中之前,浏览器需要一些时间,在这段时间内不可能运行任何脚本。
. getelementbyid(“testiframe”)。SRC语法在所有情况下都能正常工作。
链接的target属性也不能用于生成的iframe,除了在Opera中,尽管我给了我生成的iframe一个名称和id。
缺乏目标支持意味着您必须使用JavaScript来更改生成的iframe的内容,但由于您首先需要JavaScript来生成它,所以我不认为这是一个大问题。
iframe中的文本大小
Explorer 6特有的奇怪bug:
当您通过“视图”菜单更改文本大小时,iframe中的文本大小将正确更改。但是,此浏览器不会更改原始文本中的换行符,因此部分文本可能变得不可见,或者可能在行中仍然包含另一个单词时出现换行符。
下面是Nitin Bansal的回答
为了更健壮:
function getIframeWindow(iframe_object) {
var doc;
if (iframe_object.contentWindow) {
return iframe_object.contentWindow;
}
if (iframe_object.window) {
return iframe_object.window;
}
if (!doc && iframe_object.contentDocument) {
doc = iframe_object.contentDocument;
}
if (!doc && iframe_object.document) {
doc = iframe_object.document;
}
if (doc && doc.defaultView) {
return doc.defaultView;
}
if (doc && doc.parentWindow) {
return doc.parentWindow;
}
return undefined;
}
and
...
var el = document.getElementById('targetFrame');
var frame_win = getIframeWindow(el);
if (frame_win) {
frame_win.targetFunction();
...
}
...
其中一些答案并没有解决CORS问题,或者没有明确地说明您将代码段放置在何处以使通信成为可能。
这里有一个具体的例子。假设我想点击父页面上的一个按钮,并让它在iframe中做一些事情。我是这么做的。
parent_frame.html
<button id='parent_page_button' onclick='call_button_inside_frame()'></button>
function call_button_inside_frame() {
document.getElementById('my_iframe').contentWindow.postMessage('foo','*');
}
iframe_page.html
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
if(event) {
click_button_inside_frame();
}
}
function click_button_inside_frame() {
document.getElementById('frame_button').click();
}
要走另一个方向(点击iframe内的按钮调用iframe外的方法),只需切换代码片段所在的位置,并更改如下:
document.getElementById('my_iframe').contentWindow.postMessage('foo','*');
:
window.parent.postMessage('foo','*')
如果iFrame的目标和包含的文档在不同的域中,之前发布的方法可能不起作用,但有一个解决方案:
例如,如果文档A包含一个包含文档B的iframe元素,并且文档A中的脚本在文档B的Window对象上调用postMessage(),那么消息事件将在该对象上触发,标记为源自文档A的Window。文档A中的脚本可能如下所示:
var o = document.getElementsByTagName('iframe')[0];
o.contentWindow.postMessage('Hello world', 'http://b.example.org/');
要为传入事件注册事件处理程序,脚本将使用addEventListener()(或类似的机制)。例如,文档B中的脚本可能是这样的:
window.addEventListener('message', receiver, false);
function receiver(e) {
if (e.origin == 'http://example.com') {
if (e.data == 'Hello world') {
e.source.postMessage('Hello', e.origin);
} else {
alert(e.data);
}
}
}
该脚本首先检查域是否是预期的域,然后查看消息,它可以将消息显示给用户,也可以通过将消息发送回最初发送消息的文档来进行响应。
通过http://dev.w3.org/html5/postmsg/ 49岁
如果你想从另一个函数生成的iframe中调用父节点上的JavaScript函数,例如shadowbox或lightbox。
你应该尝试使用窗口对象和调用父函数:
window.parent.targetFunction();