基本上,我iframe
在页面中嵌入了代码,并且iframe
有一些JavaScript例程需要从父页面调用。
现在,相反的操作非常简单,您只需要调用parent.functionName()
,但是不幸的是,我需要恰好相反。
请注意,我的问题是不会改变的源URL的iframe
,但是调用在定义的函数iframe
。
基本上,我iframe
在页面中嵌入了代码,并且iframe
有一些JavaScript例程需要从父页面调用。
现在,相反的操作非常简单,您只需要调用parent.functionName()
,但是不幸的是,我需要恰好相反。
请注意,我的问题是不会改变的源URL的iframe
,但是调用在定义的函数iframe
。
Answers:
假设您的iFrame的ID为“ targetFrame”,而您要调用的函数为targetFunction()
:
document.getElementById('targetFrame').contentWindow.targetFunction();
您也可以使用window.frames
代替访问框架document.getElementById
。
// this option does not work in most of latest versions of chrome and Firefox
window.frames[0].frameElement.contentWindow.targetFunction();
document.getElementById('remote_iframe_0').contentWindow.my.create_element_gadget('verify_user');"
remote_iframe_0是由apache shindig服务器以编程方式创建的,但是window.parent.document.getElementById('remote_iframe_0').contentWindow.my.create_element_gadget('verify_user');"
可以正常工作
这里有一些怪癖要注意。
HTMLIFrameElement.contentWindow
可能是更简单的方法,但它不是标准属性,某些浏览器不支持它,大多数是较旧的浏览器。这是因为DOM级别1 HTML标准对此window
对象无话可说。
您也可以尝试使用HTMLIFrameElement.contentDocument.defaultView
,这是一些较旧的浏览器允许的,但IE不允许。即便如此,window
由于与(1)相同的原因,该标准并未明确表示您将对象取回,但是如果您愿意的话,可以在此处选择其他一些浏览器版本。
window.frames['name']
返回窗口是最早的,因此也是最可靠的界面。但是您必须使用一个name="..."
属性才能按名称获取框架,这有点难看/不推荐 /过渡。(id="..."
会更好,但IE不喜欢那样。)
window.frames[number]
也是非常可靠的,但是知道正确的索引是诀窍。你可以摆脱这个例如。如果您知道页面上只有一个iframe。
子iframe完全有可能尚未加载,或者有其他问题导致无法访问。您可能会发现逆向通信流程更容易:也就是说,让子iframe window.parent
在完成加载并准备好被调用时通知其脚本。通过将其自己的对象之一(例如回调函数)传递给父脚本,该父对象可以直接与iframe中的脚本进行通信,而不必担心与之关联的HTMLIFrameElement。
methode()
零件。
可以从中调用父级JS函数iframe
,但是仅当父级和加载到的页面iframe
都来自同一个域(即abc.com)并且都使用相同的协议(即两者都在http://
或上)时才可以https://
。
在以下情况下,呼叫将失败:
解决此限制的任何方法都将非常不安全。
例如,假设我注册了域名superwinningcontest.com,并发送了指向人们电子邮件的链接。当他们加载主页时,我可以iframe
在其中隐藏几秒钟并阅读他们的Facebook提要,检查最近的Amazon或PayPal交易,或者-如果他们使用的服务没有实现足够的安全性,则可以从他们的帐户中转出资金帐户。这就是JavaScript仅限于相同域和相同协议的原因。
在IFRAME中,将函数公开给window对象:
window.myFunction = function(args) {
doStuff();
}
要从父页面进行访问,请使用以下命令:
var iframe = document.getElementById("iframeId");
iframe.contentWindow.myFunction(args);
onclick()
事件仅调用window.print()
。这将打印出完美的内容iframe
。但是,当调用iframe页面的公共功能时window.print()
,如果父页面调用了公共功能,则将打印父内容。我应该如何编写代码,以便window.print()
公共函数中的调用行为与onclick
事件中的行为相同?
onclick
。您想打电话iframe.contentWindow.print()
。
document.getElementById('myFrame').contentWindow.print();' and the pubic function
这样调用的printContent()`(不是oncick事件处理程序)被这样调用window.print()
:document.getElementById('myFrame').contentWindow.printContent();
如果iFrame的目标和包含文档位于不同的域中,则先前发布的方法可能不起作用,但是有一个解决方案:
例如,如果文档A包含包含文档B的iframe元素,并且文档A中的脚本在文档B的Window对象上调用postMessage(),则将在该对象上触发消息事件,标记为源自Windows的Window文档A。文档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);
}
}
}
该脚本首先检查域是否为预期的域,然后查看消息,该消息要么显示给用户,要么通过将消息发送回文档(首先发送给该文档)来响应。
仅作记录,我今天遇到了同一问题,但是这次页面被嵌入对象而不是iframe(因为它是XHTML 1.1文档)。这是如何与对象一起使用的:
document
.getElementById('targetFrame')
.contentDocument
.defaultView
.targetFunction();
(很抱歉换行很丑,不能放在一行中)
IFRAME应该在frames[]
集合中。使用类似
frames['iframeid'].method();
method
iframe window
对象创建属性。
由于该页面现在已损坏,并且只能通过archive.org进行访问,因此在此处进行了复制:
内嵌框架
在此页面上,我将简要概述如何从它们所在的页面访问iframe。毫不奇怪,有一些浏览器注意事项。
iframe是一个内联框架,该框架虽然包含一个完全独立的页面及其自己的URL,但仍放置在另一个HTML页面中。这在网页设计中提供了非常好的可能性。问题是要访问iframe,例如将新页面加载到其中。此页面说明了操作方法。
框架还是物体?
基本问题是将iframe视为框架还是对象。
top.frames[1].frames[2]
等等)创建框架层次结构。iframe是否适合此框架层次结构?document.getElementById('theiframe'))
访问它)。一般而言,浏览器都允许在“真实”(硬编码)iframe上使用两个视图,但是生成的iframe不能作为框架进行访问。NAME属性
最重要的规则是给您创建的所有iframe name
属性,即使您也使用id
。
<iframe src="iframe_page1.html"
id="testiframe"
name="testiframe"></iframe>
大多数浏览器都需要该name
属性以使iframe成为框架层次结构的一部分。某些浏览器(尤其是Mozilla)需要使用id
来将iframe作为对象进行访问。通过将两个属性都分配给iframe,您可以保持打开状态。但是name
远不止于此id
。
访问
您可以将iframe作为对象访问并更改其src
,也可以将iframe作为框架访问并更改其location.href
。
document.getElementById('iframe_id')。src ='newpage.html'; frame ['iframe_name']。location.href ='newpage.html'; 框架语法稍微更可取,因为Opera 6支持但不支持对象语法。
访问iframe
因此,要获得完整的跨浏览器体验,您应该给iframe命名并使用
frames['testiframe'].location.href
句法。据我所知,这始终有效。
存取文件
只要使用name
属性,在iframe中访问文档就非常简单。要计算iframe中文档中的链接数,请执行
frames['testiframe'].document.links.length
。
生成的iframe
当您通过W3C DOM生成iframe时,iframe不会立即输入到frames
数组中,并且frames['testiframe'].location.href
语法。浏览器需要一些时间才能在阵列中打开iframe,在这段时间内没有脚本可以运行。
的 document.getElementById('testiframe').src
语法在所有情况下都可以正常工作。
target
链接的属性不适用于生成的iframe,但Opera中除外,即使我给了生成的iframe a name
和anid
。
缺乏 target
支持意味着您必须使用JavaScript来更改生成的iframe的内容,但是由于您首先还是需要JavaScript才能生成它,所以我认为这并不是什么大问题。
iframe中的文字大小
一个好奇的Explorer 6仅bug:
通过“视图”菜单更改文字大小时,iframe中的文字大小会正确更改。但是,此浏览器不会更改原始文本中的换行符,因此文本的一部分可能会变得不可见,或者可能在换行符仍包含另一个单词时发生换行符。
我找到了一个很好的解决方案。
如您所说,执行位于父文档中的代码非常容易。这就是我的代码的基础,反之亦然。
加载iframe时,我会调用位于父文档上的函数,并将对iframe文档中本地函数的引用作为参数传递。现在,通过此引用,父文档可以直接访问iframe的功能。
例:
在父项上:
function tunnel(fn) {
fn();
}
在iframe上:
var myFunction = function() {
alert("This work!");
}
parent.tunnel(myFunction);
加载iframe时,它将调用parent.tunnel(YourFunctionReference),它将执行参数中接收的功能。
如此简单,而不必处理各种浏览器中的所有非标准方法。
其中一些答案无法解决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','*')
继续JoelAnair的回答:
为了提高鲁棒性,请使用以下方法:
var el = document.getElementById('targetFrame');
if(el.contentWindow)
{
el.contentWindow.targetFunction();
}
else if(el.contentDocument)
{
el.contentDocument.targetFunction();
}
像魅力一样工作:)
跟随尼丁·班萨尔(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;
}
和
...
var el = document.getElementById('targetFrame');
var frame_win = getIframeWindow(el);
if (frame_win) {
frame_win.targetFunction();
...
}
...
同样的事情,但是更简单的方法是如何从iframe中的页面刷新父页面。只需调用父页面的函数即可调用javascript函数来重新加载页面:
window.location.reload();
或直接在iframe中的页面上执行此操作:
window.parent.location.reload();
两者都可以。
如果要从其他函数(例如,shadowbox或lightbox)生成的iframe上调用Parent上的JavaScript函数。
您应该尝试利用window
object并调用父函数:
window.parent.targetFunction();