Quiero llamar a una función JavaScript de ventana principal desde un iframe.
<script>
function abc()
{
alert("sss");
}
</script>
<iframe id="myFrame">
<a onclick="abc();" href="#">Call Me</a>
</iframe>
Quiero llamar a una función JavaScript de ventana principal desde un iframe.
<script>
function abc()
{
alert("sss");
}
</script>
<iframe id="myFrame">
<a onclick="abc();" href="#">Call Me</a>
</iframe>
Respuestas:
<a onclick="parent.abc();" href="#" >Call Me </a>
Ver window.parent
Devuelve una referencia al padre de la ventana o subtrama actual.
Si una ventana no tiene un elemento primario, su propiedad principal es una referencia a sí misma.
Cuando una ventana se carga en una <iframe>
, <object>
o <frame>
, su padre es la ventana con el elemento de la incorporación de la ventana.
alert
se invocará; alert
función del padre o la alert
función del iframe , en caso de que parent.abc();
se llame en el iframe?
window.postMessage()
(o window.parent.postMessage()
) existe. Compruebe la respuesta de @Andrii
Recientemente tuve que descubrir por qué esto no funcionó también.
El javascript al que desea llamar desde el iframe secundario debe estar en la cabeza del padre. Si está en el cuerpo, el script no está disponible en el ámbito global.
<head>
<script>
function abc() {
alert("sss");
}
</script>
</head>
<body>
<iframe id="myFrame">
<a onclick="parent.abc();" href="#">Click Me</a>
</iframe>
</body>
Espero que esto ayude a cualquiera que se encuentre con este problema nuevamente.
Este método permite la cross-origin
comunicación de forma segura .
Y si tiene acceso al código de la página principal, se puede llamar a cualquier método principal y también se puede pasar cualquier información directamente Iframe
. Aquí hay un pequeño ejemplo:
Página principal:
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);
}
Código de iframe:
window.parent.postMessage({
'func': 'parentFunc',
'message': 'Message text from iframe.'
}, "*");
// Use target origin instead of *
ACTUALIZACIONES:
Nota de seguridad:
Proporcione siempre un TargetOrigin específico, NO *
, si sabe dónde debe ubicarse el documento de la otra ventana. Si no se proporciona un objetivo específico, se divulgan los datos que envía a cualquier sitio malicioso interesado (comentario de ZalemCitizen ).
Referencias
He publicado esto como una respuesta separada, ya que no está relacionado con mi respuesta existente.
Este problema surgió recientemente nuevamente para acceder a un padre desde un iframe que hace referencia a un subdominio y las correcciones existentes no funcionaron.
Esta vez, la respuesta fue modificar el documento dominio de la página principal y el iframe para que sea el mismo. Esto engañará a las mismas verificaciones de la política de origen al pensar que coexisten exactamente en el mismo dominio (los subdominios se consideran un host diferente y fallan la misma verificación de la política de origen).
Inserte lo siguiente en la <head>
página en el iframe para que coincida con el dominio principal (ajuste para su doctype).
<script>
document.domain = "mydomain.com";
</script>
Tenga en cuenta que esto arrojará un error en el desarrollo localhost, por lo tanto, use una verificación como la siguiente para evitar el error:
if (!window.location.href.match(/localhost/gi)) {
document.domain = "mydomain.com";
}
example.com
iframe is abc.example.com
, then parent and iframe deben llamardocument.domain = "example.com"
Puedes usar
window.top
ver lo siguiente
<head>
<script>
function abc() {
alert("sss");
}
</script>
</head>
<body>
<iframe id="myFrame">
<a onclick="window.top.abc();" href="#">Click Me</a>
</iframe>
</body>
abc()
solo funcionarían si function abc()
se declararan en el iframe y no en la página principal. window.top.abc()
sale del iframe en el documento padre.
Otra adición para quienes lo necesitan. La solución de Ash Clarke no funciona si están usando protocolos diferentes, así que asegúrese de que si usa SSL, su iframe también usa SSL o se romperá la función. Sin embargo, su solución funcionó para los dominios en sí, así que gracias por eso.
La solución dada por Ash Clarke para subdominios funciona muy bien, pero tenga en cuenta que debe incluir el documento.domain = "mydomain.com"; tanto en el encabezado de la página de iframe como en el encabezado de la página principal, como se indica en el enlace, las mismas verificaciones de la política de origen
Una extensión importante de la misma política de origen implementada para el acceso DOM de JavaScript (pero no para la mayoría de los otros tipos de comprobaciones del mismo origen) es que dos sitios que comparten un dominio común de nivel superior pueden optar por comunicarse a pesar de fallar el "mismo host" compruebe estableciendo mutuamente su propiedad document.domain DOM correspondiente en el mismo fragmento calificado y a la derecha de su nombre de host actual. Por ejemplo, si http://en.example.com/ y http://fr.example.com/ ambos establecen document.domain en "example.com", serían desde ese punto considerados del mismo origen para el propósito de la manipulación DOM.
document.domain
?
localhost
la dirección IP de la máquina (normalmente 127.0.0.1
), dependiendo de lo que esté en la barra de direcciones URL.
parent.abc () solo funcionará en el mismo dominio debido a razones de seguridad. Probé esta solución y la mía funcionó perfectamente.
<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>
Espero que esto ayude. :)
Con Firefox y Chrome puedes usar:
<a href="whatever" target="_parent" onclick="myfunction()">
Si myfunction está presente tanto en el iframe como en el padre, se llamará al padre.
Si bien algunas de estas soluciones pueden funcionar, ninguna de ellas sigue las mejores prácticas. Muchos asignan variables globales y puede encontrarse haciendo llamadas a múltiples variables o funciones principales, lo que lleva a un espacio de nombres desordenado y vulnerable.
Para evitar esto, use un patrón de módulo. En la ventana principal:
var myThing = {
var i = 0;
myFunction : function () {
// do something
}
};
var newThing = Object.create(myThing);
Luego, en el iframe:
function myIframeFunction () {
parent.myThing.myFunction();
alert(parent.myThing.i);
};
Esto es similar a los patrones descritos en el capítulo de Herencia del texto seminal de Crockford, "Javascript: The Good Parts". También puede obtener más información en la página de w3 sobre las mejores prácticas de Javascript. https://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals