I want to call a parent window JavaScript function from an iframe.
<script>
function abc()
{
alert("sss");
}
</script>
<iframe id="myFrame">
<a onclick="abc();" href="#">Call Me</a>
</iframe>
I want to call a parent window JavaScript function from an iframe.
<script>
function abc()
{
alert("sss");
}
</script>
<iframe id="myFrame">
<a onclick="abc();" href="#">Call Me</a>
</iframe>
<a onclick="parent.abc();" href="#" >Call Me </a>
See window.parent
Returns a reference to the parent of the current window or subframe.
If a window does not have a parent, its parent property is a reference to itself.
When a window is loaded in an <iframe>
, <object>
, or <frame>
, its parent is the window with the element embedding the window.
alert
s will be invoked; parent's alert
function or iframe's alert
function, in case parent.abc();
is called on iframe? –
Monkhood window.postMessage()
(or window.parent.postMessage()
) exists. Check @Andrii answer –
Gimel This method safely enables cross-origin
communication.
And if you have access to parent page code then any parent method can be called as well as any data can be passed directly from Iframe
. Here is a small example:
Parent page:
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 code:
window.parent.postMessage({
'func': 'parentFunc',
'message': 'Message text from iframe.'
}, "*");
// Use target origin instead of *
UPDATES:
Security note:
Always provide a specific targetOrigin, NOT *
, if you know where the other window's document should be located. Failing to provide a specific target discloses the data you send to any interested malicious site (comment by ZalemCitizen).
References:
I recently had to find out why this didn't work too.
The javascript you want to call from the child iframe needs to be in the head of the parent. If it is in the body, the script is not available in the global scope.
<head>
<script>
function abc() {
alert("sss");
}
</script>
</head>
<body>
<iframe id="myFrame">
<a onclick="parent.abc();" href="#">Click Me</a>
</iframe>
</body>
Hope this helps anyone that stumbles upon this issue again.
alert
s will be invoked; parent's alert
function or iframe's alert
function, in case parent.abc();
is called on iframe? –
Monkhood You can use
window.top
see the following.
<head>
<script>
function abc() {
alert("sss");
}
</script>
</head>
<body>
<iframe id="myFrame">
<a onclick="window.top.abc();" href="#">Click Me</a>
</iframe>
</body>
abc()
would only work if function abc()
were declared in the iframe as opposed to on the parent page. window.top.abc()
breaks out of the iframe into the parent document. –
Beggary I have posted this as a separate answer as it is unrelated to my existing answer.
This issue recently cropped up again for accessing a parent from an iframe referencing a subdomain and the existing fixes did not work.
This time the answer was to modify the document.domain of the parent page and the iframe to be the same. This will fool the same origin policy checks into thinking they co-exist on exactly the same domain (subdomains are considered a different host and fail the same origin policy check).
Insert the following to the <head>
of the page in the iframe to match the parent domain (adjust for your doctype).
<script>
document.domain = "mydomain.com";
</script>
Please note that this will throw an error on localhost development, so use a check like the following to avoid the error:
if (!window.location.href.match(/localhost/gi)) {
document.domain = "mydomain.com";
}
example.com
iframe is abc.example.com
, then both parent and iframe must call document.domain = "example.com"
–
Choplogic parent.abc() will only work on same domain due to security purposes. i tried this workaround and mine worked perfectly.
<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>
Hope this helps. :)
Another addition for those who need it. Ash Clarke's solution does not work if they are using different protocols so be sure that if you are using SSL, your iframe is using SSL as well or it will break the function. His solution did work for the domains itself though, so thanks for that.
The solution given by Ash Clarke for subdomains works great, but please note that you need to include the document.domain = "mydomain.com"; in both the head of the iframe page and the head of the parent page, as stated in the link same origin policy checks
An important extension to the same origin policy implemented for JavaScript DOM access (but not for most of the other flavors of same-origin checks) is that two sites sharing a common top-level domain may opt to communicate despite failing the "same host" check by mutually setting their respective document.domain DOM property to the same qualified, right-hand fragment of their current host name. For example, if http://en.example.com/ and http://fr.example.com/ both set document.domain to "example.com", they would be from that point on considered same-origin for the purpose of DOM manipulation.
document.domain
? –
Variate localhost
or the ip address of the machine (typically 127.0.0.1
), depending on what is in the url address bar. –
Wichern While some of these solutions may work, none of them follow best practices. Many assign global variables and you may find yourself making calls to multiple parent variables or functions, leading to a cluttered, vulnerable namespace.
To avoid this, use a module pattern. In the parent window:
var myThing = {
var i = 0;
myFunction : function () {
// do something
}
};
var newThing = Object.create(myThing);
Then, in the iframe:
function myIframeFunction () {
parent.myThing.myFunction();
alert(parent.myThing.i);
};
This is similar to patterns described in the Inheritance chapter of Crockford's seminal text, "Javascript: The Good Parts." You can also learn more at w3's page for Javascript's best practices. https://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals
With Firefox and Chrome you can use :
<a href="whatever" target="_parent" onclick="myfunction()">
If myfunction is present both in iframe and in parent, the parent one will be called.
A plugin helper gist that allows the parent window to call the child iframe windows functions and vice-versa, but all calls are asynchronous.
https://gist.github.com/clinuxrulz/77f341832c6025bf10f0b183ee85e072
This will also work cross-origin, but can only call functions that you export to the iframe from the parent and the parent window can only call funtions the iframe exports.
© 2022 - 2024 — McMap. All rights reserved.