当前位置:  开发笔记 > 编程语言 > 正文

从父页面调用iframe中的JavaScript代码

如何解决《从父页面调用iframe中的JavaScript代码》经验,为你挑选了10个好方法。

基本上,我有一个iframe嵌入在页面中,并iframe有一些我需要从父页面调用的JavaScript例程.

现在相反的情况非常简单,因为你只需要打电话parent.functionName(),但不幸的是,我需要完全相反.

请注意,我的问题是不会改变的源URL的iframe,但是调用在定义的函数iframe.



1> Joel Anair..:

假设您的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(); 


@JellicleCat这是因为父页面和iframe具有不同的主机,使其成为跨源框架,如消息所示.只要父页面的协议,域和端口与iframe匹配,一切都会正常工作.
适用于FF 7,Chrome 12,IE 8/9和Safari(不确定此版本)
这个解决方案对我的小工具不起作用,这里是我的代码`document.getElementById('remote_iframe_0').contentWindow.my.create_element_gadg et('verify_user');"`remote_iframe_0是由apache shindig服务器编程创建的,但``window .parent.document.getElementById('remote_iframe_0').contentWindow.my.create_element_gadg et('verify_user');"`的作品
@Dirty Henry你的"jQuery函数"是什么意思?jQuery是一个JavaScript库.

2> bobince..:

这里有一些需要注意的怪癖.

    HTMLIFrameElement.contentWindow可能是更简单的方法,但它不是一个标准的属性,有些浏览器不支持它,主要是较旧的.这是因为DOM Level 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.


好东西!特别是你的建议5.已经证明非常有价值.在尝试从Chrome中的父级访问iFrame功能时,它解决了我很多麻烦.将功能对象从iFrame中传出,使其在Chrome,FF甚至是IE中从9到7运行,并且还可以很容易地检查功能是否已经加载.谢谢!

3> Vivek Singh ..:

可以调用父JS函数iframe,但只有当父iframe元素和加载的页面都来自同一个域,即abc.com时,两者都使用相同的协议,即两者都是on http://或者https://.

在下面提到的情况下,呼叫将失败:

    父页面和iframe页面来自不同的域.

    他们使用不同的协议,一个在http://上,另一个在https://上.

这种限制的任何解决方法都是非常不安全的.

例如,假设我注册了域名superwinningcontest.com并发送了人们电子邮件的链接.当他们加载主页时,我可以iframe在那里隐藏几个并阅读他们的Facebook提要,查看最近的亚马逊或PayPal交易,或者 - 如果他们使用的服务没有实现足够的安全性 - 将资金从他们的账户.这就是为什么JavaScript仅限于同域和同一协议.


解决方法是使用美丽而危险的http://en.wikipedia.org/wiki/Cross-document_messaging

4> Tomalak..:

在IFRAME中,将您的函数公开给window对象:

window.myFunction = function(args) {
   doStuff();
}

要从父页面进行访问,请使用以下命令:

var iframe = document.getElementById("iframeId");
iframe.contentWindow.myFunction(args);



5> 19greg96..:

如果iFrame和包含文档位于不同的域上,则先前发布的方法可能不起作用,但有一个解决方案:

例如,如果文档A包含包含文档B的iframe元素,并且文档A中的脚本在文档B的Window对象上调用postMessage(),则将在该对象上触发消息事件,标记为源自Window of 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);
    }
  }
}

此脚本首先检查域是否是预期的域,然后查看它显示给用户的消息,或者通过向首先发送消息的文档发送消息来响应.

通过http://dev.w3.org/html5/postmsg/#web-messaging



6> Tamas Czineg..:

仅仅是为了记录,我今天遇到了同样的问题,但这次页面嵌入了一个对象,而不是iframe(因为它是一个XHTML 1.1文档).以下是它如何与对象一起使用:

document
  .getElementById('targetFrame')
  .contentDocument
  .defaultView
  .targetFunction();

(抱歉丑陋的换行符,不适合单行)



7> activout.se..:

Quirksmode有一个帖子.

由于页面现在已经破了,只能通过archive.org访问,我在这里复制了它:

的IFrame

在这个页面上,我简要概述了从他们所在的页面访问iframe.毫不奇怪,有一些浏览器考虑因素.

iframe是一个内联框架,一个框架虽然包含一个完全独立的页面,但有一个自己的URL,但仍然放在另一个HTML页面中.这为网页设计提供了非常好的可能性.问题是访问iframe,例如将新页面加载到其中.本页介绍了如何操作.

框架还是物体?

根本问题是iframe是被视为一个框架还是一个对象.

正如框架页面简介中所述,如果使用框架,浏览器会为您创建框架层次结构(top.frames[1].frames[2]等等).iframe是否适合此框架层次结构?

或者浏览器是否将iframe视为另一个对象,一个恰好具有src属性的对象?在这种情况下,我们必须使用标准的DOM调用(比如document.getElementById('theiframe'))访问它.一般来说,浏览器允许在'真实'(硬编码)iframe上的两个视图,但生成的iframe不能作为帧访问.

NAME属性

最重要的规则是给你创建name属性的任何iframe ,即使你也使用了id.


大多数浏览器需要该name属性来构成帧层次结构的iframe部分.某些浏览器(特别是Mozilla)需要id将iframe作为对象进行访问.通过将这两个属性分配给iframe,您可以打开选项.但name远比重要id.

访问

您可以将iframe作为对象访问并更改它,src或者您将iframe作为一个框架进行访问并更改它location.href.

document.getElementById('iframe_id').src ='newpage.html'; frames ['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除了Opera之外,链接的属性对生成的iframe都不起作用,即使我将生成的iframe都给了a name和a id.

缺乏target支持意味着您必须使用JavaScript来更改生成的iframe的内容,但是因为您首先需要JavaScript来生成它,所以我不认为这是一个很大的问题.

iframe中的文字大小

一个好奇的Explorer 6唯一的bug:

通过"视图"菜单更改文本大小时,iframe中的文本大小会正确更改.但是,此浏览器不会更改原始文本中的换行符,因此文本的一部分可能会变为不可见,或者当行仍然可以保留另一个单词时可能会出现换行符.


该链接似乎被打破了.

8> dkretz..:

IFRAME应该在frames[]收藏中.使用类似的东西

frames['iframeid'].method();



9> Julien L..:

我找到了一个很优雅的解决方案

正如您所说,执行位于父文档上的代码相当容易.这是我的代码的基础,恰恰相反.

当我的iframe加载时,我调用位于父文档上的函数,作为参数传递对位于iframe文档中的本地函数的引用.现在,父文档可以通过此引用直接访问iframe的功能.

例:

在父母身上:

function tunnel(fn) {
    fn();
}

关于iframe:

var myFunction = function() {
    alert("This work!");
}

parent.tunnel(myFunction);

当iframe加载时,它将调用parent.tunnel(YourFunctionReference),它将执行参数中接收的函数.

这很简单,无需处理来自各种浏览器的所有非标准方法.



10> Cybernetic..:

其中一些答案无法解决CORS问题,或者无法在放置代码段的地方变得显而易见,从而可以进行通信。

这是一个具体的例子。假设我想点击父页面上的按钮,然后在iframe中执行某些操作。这就是我要怎么做。

parent_frame.html



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','*')

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有