web-dev-qa-db-ja.com

iframeから親ウィンドウ関数を呼び出す

Iframeから親ウィンドウのJavaScript関数を呼び出したい。

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

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

window.parent を参照してください。

現在のウィンドウまたはサブフレームの親への参照を返します。

ウィンドウに親がない場合、そのparentプロパティはそれ自体への参照です。

ウィンドウが<iframe><object>、または<frame>にロードされるとき、その親はウィンドウを埋め込む要素を持つウィンドウです。

413
rahul

私は最近これがあまりにもうまくいかなかった理由を見つけなければなりませんでした。

子のiframeから呼び出すJavaScriptは、親の先頭にある必要があります。本体にある場合、スクリプトはグローバルスコープでは使用できません。

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

これがこの問題に再び遭遇する誰かに役立つことを願っています。

76
Ash Clarke

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.'
}, "*");

参考文献:

52

これは私の既存の回答とは無関係なので、私はこれを別の回答として投稿しました。

この問題は最近、サブドメインを参照しているiframeから親にアクセスするために再び発生し、既存の修正は機能しませんでした。

今回の答えは、親ページのdocument.domainとiframeが同じになるように修正することでした。これは、 同じOriginポリシーチェック が、それらがまったく同じドメイン上に共存している(サブドメインは異なるHostと見なされ、同じOriginポリシーに失敗する)ことを欺くでしょうチェック)。

Iframe内のページの<head>に、親ドメインと一致するように次のコードを挿入します(Doctypeに合わせて調整します)。

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

これはlocalhostの開発時にエラーを発生させるので、エラーを回避するために次のようなチェックを使用してください。

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

あなたが使用することができます

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>

それを必要とする人々のためのもう一つの追加。 Ash Clarkeのソリューションは、異なるプロトコルを使用している場合は機能しません。SSLを使用している場合は、iframeがSSLも使用しているかどうかを確認してください。彼の解決策はドメイン自体にも有効でした、それではありがとう。

3
Devon

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>

お役に立てれば。 :)

2
Seph Remotigue

Ash Clarkeがサブドメインに対して提供した解決策はうまくいきますが、document.domain = "mydomain.com"を含める必要があることに注意してください。リンク に記載されているように、iframeページの先頭と親ページの先頭の両方に同じOriginポリシーチェック があります。

JavaScript DOMアクセスに対して実装された同じOriginポリシーに対する重要な拡張(ただし、同じOriginクラスの他の種類の同じOriginチェックには当てはまりません)は、「同じホスト」に失敗しても共通のトップレベルドメインを共有する2つのサイトが通信を選択できるそれぞれのdocument.domain DOMプロパティを、現在のホスト名の同じ修飾された右側のフラグメントに相互に設定して確認します。たとえば、 http://en.example.com/ および http://fr.exampleの場合です。 com / は両方ともdocument.domainを "example.com"に設定します。DOM操作の目的のために、その時点から同じOriginと見なされます。

2
Frato

FirefoxとChromeでは、次のものを使用できます。

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

Myfunctionがiframeとparentの両方に存在する場合、parent関数が呼び出されます。

1
snowflake

これらの解決策のいくつかはうまくいくかもしれませんが、どれもベストプラクティスに従いません。多くの人がグローバル変数を代入していて、あなたが自分で複数の親変数や関数を呼び出しているのに気付くかもしれません。

これを回避するには、モジュールパターンを使用してください。親ウィンドウで:

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の精液テキスト「Javascript:The Good Parts」の「継承」の章で説明されているパターンと似ています。 JavaScriptのベストプラクティスについては、w3のページでも学ぶことができます。 https://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals