从iframe调用父窗口函数

时间:2010-01-29 10:53:42

标签: javascript iframe onclick

我想从iframe调用父窗口JavaScript函数。

<script>
    function abc()
    {
        alert("sss");
    }
</script>

<iframe id="myFrame">
    <a onclick="abc();" href="#">Call Me</a>
</iframe>

10 个答案:

答案 0 :(得分:411)

<a onclick="parent.abc();" href="#" >Call Me </a>

请参阅window.parent

返回对当前窗口或子帧的父级的引用。

如果窗口没有父窗口,则其父属性是对自身的引用。

当在<iframe><object><frame>中加载窗口时,其父窗口是嵌入窗口的元素的窗口。

答案 1 :(得分:76)

我最近不得不找出为什么这也不起作用。

您要从子iframe调用的javascript需要位于父级的头部。如果它在正文中,则脚本在全局范围内不可用。

<head>
    <script>
    function abc() {
        alert("sss");
    }
    </script>
</head>
<body>
    <iframe id="myFrame">
        <a onclick="parent.abc();" href="#">Click Me</a>
    </iframe>
</body>

希望这可以帮助任何再次遇到此问题的人。

答案 2 :(得分:49)

Window.postMessage()

此方法可安全地启用cross-origin通信。

如果您可以访问父页面代码,则可以调用任何父方法,也可以直接从Iframe传递任何数据。这是一个小例子:

父页:

if (window.addEventListener) {
    window.addEventListener("message", onMessage, false);        
} 
else if (window.attachEvent) {
    window.attachEvent("onmessage", onMessage, false);
}

function onMessage(event) {
    // Check sender origin to be trusted
    if (event.origin !== "http://example.com") return;

    var data = event.data;

    if (typeof(window[data.func]) == "function") {
        window[data.func].call(null, data.message);
    }
}

// Function to be called from iframe
function parentFunc(message) {
    alert(message);
}

iframe代码:

window.parent.postMessage({
    'func': 'parentFunc',
    'message': 'Message text from iframe.'
}, "*");

<强>参考文献:

答案 3 :(得分:19)

我已将此作为单独的答案发布,因为它与我现有的答案无关。

此问题最近再次出现,用于从引用子域的iframe访问父级,并且现有修补程序不起作用。

这次的答案是修改父页面的document.domain和iframe是相同的。这会欺骗same origin policy checks认为它们在完全相同的域上共存(子域被视为不同的主机并且无法通过相同的原始策略检查)。

将以下内容插入iframe页面的<head>以匹配父域名(根据您的doctype进行调整)。

<script>
    document.domain = "mydomain.com";
</script>

请注意,这会在localhost开发中引发错误,因此请使用以下检查来避免错误:

if (!window.location.href.match(/localhost/gi)) {
    document.domain = "mydomain.com";
} 

答案 4 :(得分:15)

您可以使用

window.top

请参阅以下内容。

<head>
    <script>
    function abc() {
        alert("sss");
    }
    </script>
</head>
<body>
    <iframe id="myFrame">
        <a onclick="window.top.abc();" href="#">Click Me</a>
    </iframe>
</body>

答案 5 :(得分:3)

需要它的人的另一个补充。如果使用不同的协议,Ash Clarke的解决方案不起作用,所以请确保如果您使用的是SSL,那么您的iframe也会使用SSL,否则会破坏该功能。他的解决方案确实适用于域名本身,所以非常感谢。

答案 6 :(得分:2)

Ash Clarke为子域名提供的解决方案效果很好,但请注意,您需要包含document.domain =“mydomain.com”;在iframe页面的头部和父页面的头部,如链接same origin policy checks中所述

  

为JavaScript DOM访问实现的相同原始策略的重要扩展(但对于大多数其他类型的同源检查不是这样),共享一个公共顶级域的两个站点可能会选择进行通信,尽管“同一主机“通过将各自的document.domain DOM属性相互设置为其当前主机名的相同限定右侧片段进行检查。   例如,如果http://en.example.com/http://fr.example.com/都将document.domain设置为“example.com”,则为了DOM操作的目的,它们将从被认为是同源的那一点开始。

答案 7 :(得分:2)

parent.abc()仅出于安全考虑,才能在同一个域上运行。我尝试了这种解决方法,并且我的工作非常完美。

<head>
    <script>
    function abc() {
        alert("sss");
    }

    // window of the iframe
    var innerWindow = document.getElementById('myFrame').contentWindow;
    innerWindow.abc= abc;

    </script>
</head>
<body>
    <iframe id="myFrame">
        <a onclick="abc();" href="#">Click Me</a>
    </iframe>
</body>

希望这会有所帮助。 :)

答案 8 :(得分:1)

使用Firefox和Chrome,您可以使用:

<a href="whatever" target="_parent" onclick="myfunction()">

如果在iframe和父级中都存在myfunction,则会调用父级。

答案 9 :(得分:0)

虽然其中一些解决方案可行,但它们都没有遵循最佳实践。许多人分配全局变量,你可能会发现自己调用多个父变量或函数,导致一个混乱,易受攻击的命名空间。

要避免这种情况,请使用模块模式。在父窗口中:

var myThing = {
    var i = 0;
    myFunction : function () {
        // do something
    }
};

var newThing = Object.create(myThing);

然后,在iframe中:

function myIframeFunction () {
    parent.myThing.myFunction();
    alert(parent.myThing.i);
};

这类似于Crockford的开创性文本的继承章节中描述的模式,&#34; Javascript:The Good Parts。&#34;您还可以在w3的页面上了解有关Javascript最佳做法的更多信息。 https://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals