web-dev-qa-db-fra.com

Appeler une fonction de fenêtre parente depuis un iframe

Je souhaite appeler une fonction JavaScript de la fenêtre parente à partir d'un iframe.

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

<iframe id="myFrame">
    <a onclick="abc();" href="#">Call Me</a>
</iframe>
262
Arjun Singh
<a onclick="parent.abc();" href="#" >Call Me </a>

Voir window.parent

Renvoie une référence au parent de la fenêtre ou de la sous-trame actuelle.

Si une fenêtre n'a pas de parent, sa propriété parent est une référence à elle-même.

Lorsqu'une fenêtre est chargée dans un <iframe>, <object> ou <frame>, son parent est la fenêtre avec l'élément incorporant la fenêtre.

416
rahul

J'ai récemment dû découvrir pourquoi cela ne fonctionnait pas aussi.

Le javascript que vous voulez appeler depuis l'iframe enfant doit être dans la tête du parent. S'il est dans le corps, le script n'est pas disponible dans la portée globale.

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

J'espère que cela aidera tous ceux qui trébuchent à nouveau sur cette question.

76
Ash Clarke

Window.postMessage ()

Cette méthode active en toute sécurité la communication cross-Origin.

Et si vous avez accès au code de page parent, vous pouvez appeler n'importe quelle méthode mère et transmettre directement les données de Iframe. Voici un petit exemple:

Page parent:

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);
}

Code Iframe:

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

Références:

55
Andrii Verbytskyi

J'ai posté ceci en tant que réponse séparée car elle n'a aucun lien avec ma réponse existante.

Ce problème a récemment été abordé à nouveau pour l'accès à un parent depuis une iframe référençant un sous-domaine et les correctifs existants ne fonctionnaient pas.

Cette fois, la réponse a été de modifier le document.domain de la page parent et le iframe pour qu'ils soient identiques. Cela incitera les mêmes contrôles de stratégie d'origine à penser qu'ils coexistent exactement sur le même domaine (les sous-domaines sont considérés comme un hôte différent et échouent à la même vérification de stratégie d'origine).

Insérez ce qui suit dans le <head> de la page dans l'iframe pour correspondre au domaine parent (ajustez en fonction de votre type de document).

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

S'il vous plaît noter que cela va jeter une erreur sur le développement localhost, donc utilisez une vérification comme suit pour éviter l'erreur:

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

Vous pouvez utiliser

window.top

voir ce qui suit.

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

Un autre ajout pour ceux qui en ont besoin. La solution de Ash Clarke ne fonctionne pas s’ils utilisent différents protocoles. Assurez-vous donc que si vous utilisez SSL, votre iframe utilise également SSL sinon, sa fonction sera interrompue. Sa solution a toutefois fonctionné pour les domaines eux-mêmes, alors merci pour cela.

3
Devon

parent.abc () ne fonctionnera que sur le même domaine pour des raisons de sécurité. J'ai essayé cette solution de contournement et le mien a fonctionné parfaitement.

<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>

J'espère que cela t'aides. :)

2
Seph Remotigue

La solution proposée par Ash Clarke pour les sous-domaines fonctionne très bien, mais veuillez noter que vous devez inclure le document.domain = "mydomain.com"; dans l'en-tête de la page d'iframe et dans l'en-tête de la page parent, comme indiqué dans le lien mêmes contrôles de stratégie d'origine

Une extension importante de la même stratégie Origin implémentée pour l'accès DOM JavaScript (mais pas pour la plupart des autres types de vérifications de même origine) est que deux sites partageant un domaine de niveau supérieur commun peuvent choisir de communiquer malgré l'échec du "même hôte". vérifiez en définissant mutuellement leur propriété DOM document.domain respective sur le même fragment de droite qualifié de leur nom d'hôte actuel. Par exemple, si http://en.example.com/ et http://fr.example.com/ , définissez document.domain sur "example.com". , ils seraient à partir de ce moment-là considérés comme de même origine aux fins de la manipulation du DOM.

2
Frato

Avec Firefox et Chrome, vous pouvez utiliser:

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

Si ma fonction est présente à la fois dans iframe et dans parent, celle-ci sera appelée.

1
snowflake

Certaines de ces solutions peuvent fonctionner, mais aucune d’elles ne respecte les meilleures pratiques. Beaucoup assignent des variables globales et vous pouvez être amené à faire des appels à plusieurs variables ou fonctions parent, ce qui conduit à un espace de noms encombré et vulnérable.

Pour éviter cela, utilisez un modèle de module. Dans la fenêtre parente:

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

var newThing = Object.create(myThing);

Ensuite, dans l'iframe:

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

Ceci est similaire aux modèles décrits dans le chapitre Héritage du texte fondateur de Crockford, "Javascript: The Good Parts". Vous pouvez également en savoir plus sur la page w3 pour connaître les meilleures pratiques en Javascript. https://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals