关于html:从父页面调用iframe中的JavaScript代码

Invoking JavaScript code in an iframe from the parent page

基本上,我在页面中嵌入了一个iframe,而iframe有一些需要从父页面调用的javascript例程。

现在,相反的情况很简单,因为您只需要调用parent.functionName(),但不幸的是,我需要的恰恰相反。

请注意,我的问题不是更改iframe的源URL,而是调用iframe中定义的函数。


假设您的iframe的id是"targetframe",您要调用的函数是targetFunction()

1
document.getElementById('targetFrame').contentWindow.targetFunction();

您也可以使用window.frames而不是document.getElementById访问帧。

1
2
// this option does not work in most of latest versions of chrome and Firefox
window.frames[0].frameElement.contentWindow.targetFunction();


这里有一些怪癖需要注意。

  • HTMLIFrameElement.contentWindow可能是更简单的方法,但它不是一个标准属性,有些浏览器不支持它,大多数是旧的。这是因为DOMLevel1HTML标准对window对象没有任何意义。

  • 你也可以尝试使用HTMLIFrameElement.contentDocument.defaultView,这是一些老版本的浏览器允许的,但IE不允许。尽管如此,标准并没有明确地说你得到了window对象,原因与(1)相同,但是如果你愿意,你可以在这里选择一些额外的浏览器版本。

  • 返回窗口的window.frames['name']是最古老的,因此也是最可靠的接口。但是您随后必须使用name="..."属性才能按名称获取帧,这是稍微难看的/已弃用/transitional。(id="..."会更好,但我不喜欢那样。)

  • window.frames[number]也是非常可靠的,但是知道正确的指数是关键。如果你知道你的页面上只有一个iframe,你就可以摆脱这种困境。

  • 完全可能是子iframe尚未加载,或者是其他错误导致无法访问。您可能会发现逆转通信流更容易:也就是说,当子iframe完成加载并准备被调用时,让它通知它的window.parent脚本。通过将它自己的一个对象(例如回调函数)传递给父脚本,该父脚本就可以直接与iframe中的脚本通信,而不必担心与之关联的htmliFrameElement。


  • 可以从iframe调用父JS函数,但前提是父JS函数和加载在iframe中的页面都来自相同的域,即abc.com,并且两者使用相同的协议,即两者都在http://https://上。

    在以下情况下,呼叫将失败:

  • 父页和iframe页来自不同的域。
  • 他们使用不同的协议,一个在http://上,另一个在https://上。
  • 任何解决这一限制的方法都是非常不安全的。

    例如,假设我注册了域名superwiningcompute.com并发送了指向人们电子邮件的链接。当他们加载主页时,我可以在里面隐藏一些EDCX1 9个s,读取他们的脸谱网feed,查看最近的亚马逊或PayPal交易,或者——如果他们使用的服务没有实现足够的安全性——把钱从他们的账户中转移出去。这就是为什么JavaScript被限制在相同的域和相同的协议中。


    在iframe中,将函数公开给window对象:

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

    若要从父页访问,请使用:

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


    (P)如果《国际财务报告准则》和其中所载的文件是关于不同领域的,则所采用的方法可能不起作用,但有一个解决办法:(p)(P)For example,if document A contains an IFRAME element that contains document B,and script in document a calls postmessage(……)on the window object of document B,they a message event will be fired on that object,marked as originating from the window of document A.The script in document a might look like:(p)字母名称(P)为了记录可能发生的收入事件,该脚本将使用额外的事件()(或类似的机制)。For example,the script in document B might look like:(p)字母名称(P)This script first checks the domain is the expected domain,and they look at the message,which it either displays to the user,or responds to by sending a message back to the document which sent the message in the first place.(p)(P)Via http://dev.w3.org/html5/postmsg/.35Web-Messaging(p)


    只是为了记录,我今天遇到了同样的问题,但这次页面是嵌入在一个对象中的,而不是一个iframe(因为它是一个xhtml 1.1文档)。以下是它如何处理对象:

    1
    2
    3
    4
    5
    document
      .getElementById('targetFrame')
      .contentDocument
      .defaultView
      .targetFunction();

    (不好意思出现难看的断线,不适合一行)


    iframe应该在frames[]集合中。使用类似的东西

    1
    frames['iframeid'].method();


    Qurksmode对此有过报道。

    由于该页面现在已被破坏,并且只能通过archive.org访问,所以我在这里复制了它:

    iFrAMES

    在本页中,我简要概述了如何从其所在的页面访问iframes。不足为奇,有一些浏览器方面的考虑。

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

    框架还是物体?

    基本问题是iframe是被视为框架还是对象。

    • 如"框架介绍"页面中所述,如果使用框架,浏览器将为您创建框架层次结构(top.frames[1].frames[2]等)。iframe是否适合此框架层次结构?
    • 或者浏览器是否将iframe视为另一个对象,一个恰好具有src属性的对象?在这种情况下,我们必须使用标准的DOM调用(如document.getElementById('theiframe'))来访问它。一般来说,浏览器允许对"real"(硬编码)iframe的两个视图,但生成的iframe不能作为帧访问。

    名称属性

    最重要的规则是为您创建的任何iframe提供name属性,即使您也使用id属性。

    1
    2
    3
    <iframe src="iframe_page1.html"
        id="testiframe"
        name="testiframe"></iframe>

    大多数浏览器都需要name属性来使iframe成为框架层次结构的一部分。一些浏览器(特别是Mozilla)需要id使iframe作为对象可访问。通过将这两个属性分配给iframe,可以保持选项的打开状态。但是nameid重要得多。

    通路

    您可以将iframe作为对象访问并更改其src,也可以将iframe作为帧访问并更改其location.href

    document.getElementByID('iframe_id').src='newpage.html';frames['iframe_name'].location.href='newpage.html';框架语法稍好一点,因为Opera6支持它,但不支持对象语法。

    访问iframe

    因此,要获得完整的跨浏览器体验,您应该为iframe命名并使用

    1
    frames['testiframe'].location.href

    语法。据我所知,这总是有效的。

    访问文档

    如果您使用name属性,那么访问iframe中的文档非常简单。要计算iframe中文档中的链接数,请执行以下操作:frames['testiframe'].document.links.length

    生成的iframes

    但是,当通过W3C DOM生成iframe时,iframe不会立即输入到frames数组中,frames['testiframe'].location.href语法不会立即起作用。在数组中出现iframe之前,浏览器需要一点时间,在这个时间段内没有脚本可以运行。

    document.getElementById('testiframe').src语法在任何情况下都可以正常工作。

    链接的target属性既不适用于生成的iframe,也不适用于opera,尽管我将生成的iframe同时提供了nameid

    缺少target支持意味着您必须使用javascript来更改生成的iframe的内容,但是由于您首先需要javascript来生成iframe,所以我认为这不是什么问题。

    iframes中的文本大小

    一个好奇的探险家6唯一的错误:

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


    (P)我找到了一个优雅的解决方案(p)(P)As you said,it's fairly easy to execute code located on the parent document.And that's the base of my code,do to just the opposite.(p)(P)When my iframe loads,I call a function located on the parent document,passing a s an argument a reference to a local function,located in the IFRAME's document.The parent document now has a direct access to the IFRAME's function thru this reference.(p)(P)例如:(p)(P)On the parent:(p)字母名称(P)On the IFRAME:(p)字母名称(P)When the IFRAME loads,it will call parent.tunnel(Yourfunctionreference),which will execute the function received in parameter.(p)(P)这是很简单的,没有经过处理与所有非标准方法从各种布劳斯蛋糕。(p)


    (P)Some of these answers don't address the cors issue,or don't make it obvious where you place the code snippets to make the communication possible.(p)(P)这是一个具体的例子。Say I want to clik a button on the parent page,and have that do some inside the IFRAME.这就是我想做的。(p)(P)Parent U Frame.html(p)字母名称(P)Ifme UU page.html(p)字母名称(P)To go the other direction(click button inside ifme to call method outside IFRAME)just switch where the code snippet live,and change this:(p)字母名称(P)To this:(p)字母名称


    继续Joelanair的回答:

    为了更稳健性,使用如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var el = document.getElementById('targetFrame');

    if(el.contentWindow)
    {
       el.contentWindow.targetFunction();
    }
    else if(el.contentDocument)
    {
       el.contentDocument.targetFunction();
    }

    像魅力一样工作:)


    (P)Folowing Nitin Bansal's Answer(p)(P)And for even more strongness:(p)字母名称(P)and(p)字母名称


    1
    2
    3
           $("#myframe").load(function() {
                alert("loaded");
            });

    同样的事情,但是更简单的方法是如何在iframe中从页面刷新父页面。只需调用父页面的函数来调用javascript函数来重新加载页面:

    1
    window.location.reload();

    或者直接从iframe中的页面执行此操作:

    1
    window.parent.location.reload();

    两者都有效。


    (P)If we want call the parent page javascript function from the IFRAME which generated from the coding.Ex Shadowbox or Lightbox(p)(P)Window.parent.targetfunction();(p)


    (P)Try just EDOCX1音标0(p)


    (P)Use following to call function of a frame in parent page(p)字母名称