JavaScriptから親iframeにアクセスする方法


170

さて、私は同じドメインページを呼び出すIFrameを持っています。私の問題は、この呼び出されたページ(JavaScriptから)からこの親Iframeの情報にアクセスしたいことです。このiframeにアクセスするにはどうすればよいですか?

詳細:Windows環境をプログラミングしているため、このページと同じように、同じページをロードできるiframeがいくつかあります。私はこのiframeを閉じるつもりです。そのため、彼の内側からどちらを閉じるかを知る必要があります。これらのiframeへの参照を保持する配列があります。

編集:iframeが動的に生成されます


iframeが動的に生成される場合でも、なんらかのカウンターを使用して新しい一意のIDを割り当てることができます。最後にIDを知る必要はありませんが、簡単に検索できます。私の回答を参照してください。
Akash Kava

回答:


138

また、名前とIDを同じ値に設定できます

<iframe id="frame1" name="frame1" src="any.html"></iframe>

子ページ内で次のコードを使用できるようになります

parent.document.getElementById(window.name);

16
多分それは誰にとっても明白ではないかもしれませんが、このメソッドを使用すると、親のライブラリオブジェクトにアクセスできます(親がすでにライブラリをロードしている場合のみ)。例:parent。$( '
#something

1
このソリューションは、IE5 +互換性互換モードと互換性があります。
Slayner

2016年でさえ、これはIEがiframe小さすぎるコンテンツを印刷する問題の解決策の一部としてうまく機能します。しかし、なぜそれが機能するのですか?window.name文字列を返します。使用に関してwindow.name、機能しない文字列としてID名を渡すだけと何が違うのですか?)
Karl

3
こんにちは、それは...クローム59で実行されません:VM111:1キャッチされない例外:DOMException:起源「でブロックされたフレームXXXクロスオリジンフレームにアクセスするから」。
Didier68 2017

CORSが設定されていない場合、Chromeはクロスオリジンと同じフォルダー内のファイルを参照します。彼らはそれがセキュリティのためであると言います。CORSの設定にはサーバーが必要です。サーバーをセットアップするか、Chromeが検出された場合はブラウザを変更するようユーザーにメッセージを送信します。

90

window.frameElementフレーム付きページから呼び出すだけです。ページがフレーム内にない場合は、にframeElementなりますnull

もう1つの方法(フレーム内にウィンドウ要素を取得するのはそれほど簡単ではありません)ですが、完全を期すためです。

/**
 * @param f, iframe or frame element
 * @return Window object inside the given frame
 * @effect will append f to document.body if f not yet part of the DOM
 * @see Window.frameElement
 * @usage myFrame.document = getFramedWindow(myFrame).document;
 */
function getFramedWindow(f)
{
    if(f.parentNode == null)
        f = document.body.appendChild(f);
    var w = (f.contentWindow || f.contentDocument);
    if(w && w.nodeType && w.nodeType==9)
        w = (w.defaultView || w.parentWindow);
    return w;
}

2
ありがとう!IE 6 +、FF、Chromeで動作します!
rustyx 2014年

11
window.frameElementnullwindowとiframeのドメインが異なる場合、つまりクロスオリジンメッセージングの場合に返されます。
Qwerty

@Qwerty、何か解決策を見つけましたか?
Ajay Patidar

@AjayPatidarあきらめたと思います。:(
Qwerty

78

postMessage APIの使用をお勧めします

iframeで、次を呼び出します。

window.parent.postMessage({message: 'Hello world'}, 'http://localhost/');

iframeを組み込んだページでは、次のようなイベントをリッスンできます。

window.addEventListener('message', function(event) {
      if(event.origin === 'http://localhost/')
      {
        alert('Received message: ' + event.data.message);
      }
      else
      {
        alert('Origin not allowed!');
      }

    }, false);

ところで、iframeだけでなく、他のウィンドウへの呼び出しも可能です。

John ResigsブログのpostMessage APIについて詳しくは、こちらをご覧ください。


7
これは明らかに最良の答えだと思います。<iframe>コンテンツは親について何も知る必要がなく、その逆も同様です。単純なメッセージコントラクトに従うだけで済みます。驚くばかり!
mfeineis 2014年

1
<iframe>はまだ親のドメインを知っている必要がありますよね?
Homr Zodyssey 2016年

1
@HomrZodyssey親ドメインは安全メカニズムとしてのみ使用でき、不明な場合は設定できます'*'
Amir Ali Akbari 2017年

'*'クライアントで使用します。他のすべての解決策は、サーバーが設定されていないため、クライアントフォルダー内のファイルを同じ生成元ではないものとして扱うChromeブラウザーでエラーを出します。これが最善かつ唯一のソリューションです。dyn

30

古い質問ですが、同じ問題があり、iframeを取得する方法を見つけました。これは、親ウィンドウのframes []配列を反復処理し、コードが実行されているウィンドウに対して各フレームのcontentWindowをテストするだけの問題です。例:

var arrFrames = parent.document.getElementsByTagName("IFRAME");
for (var i = 0; i < arrFrames.length; i++) {
  if (arrFrames[i].contentWindow === window) alert("yay!");
}

または、jQueryを使用します。

parent.$("iframe").each(function(iel, el) {
  if(el.contentWindow === window) alert("got it");
});

この方法を使用すると、各iframeにIDを割り当てる手間が省けます。これは、動的に作成されるため、この場合に適しています。window.parentを使用してiframe要素を取得できないため、これ以上直接的な方法は見つかりませんでした。親のwindow要素に直接移動します(iframeをスキップします)。したがって、IDを使用したくない場合を除いて、それらをループすることが唯一の方法のようです。


1
更新:これは宣伝どおりに機能せず、contentWindow.document === documentを使用する必要がありました。なぜだかわかりません。また、一部のブラウザーではcontentDocumentを使用しました。まあ、私はそれが好きです!
クリストフ

1
申し訳ありませんが、私はFirefoxでのみテストしました。:)しかし、私は複数のブラウザーでjQueryメソッドとcontentWindowを使用して成功しました。
成分

1
更新:window.frameElementも使用できることがわかりましたが、どのブラウザーがそれをサポートしているかはわかりません。
Christophe

2
このタイプのものはもう機能しないと思います。クロスオリジンエラーが発生します。
Andrew Mao

@AndrewMao質問は同じオリジンドキュメントに関するものなので、クロスオリジンの問題が発生する理由はありません。
クリストフ

21

を使用parentして親ページにアクセスできます。したがって、関数にアクセスするには、次のようになります。

var obj = parent.getElementById('foo');

1
ケビン、問題はIDを知ることです。I複数のIフレームを持っている、と私は、コードの内部からそれらにアクセスしたい
ホセ・レアル

それでも、「ブロック元のフレームがother-localhost:8000のフレームがクロスオリジンフレームにアクセスできないようにブロックされています」と表示されます。
user2568374

13

iframeのidが設定されると、以下に示すように、内部ドキュメントからiframeにアクセスできます。

var iframe = parent.document.getElementById(frameElement.id);

IE、Chrome、FFで正常に動作します。


これは複雑な方法のようですvar iframe = frameElement
Oriol

frameElementは現在のウィンドウコンテキストでオブジェクトを返しますが、parent.document.getElementById(frameElement.id)は親ウィンドウコンテキストでオブジェクトを返します。frameElementで親ウィンドウのJavaScript関数を実行することはできません。jsfiddleで試して、できれば例を挙げてください。 。
Akash Kava

6

多分ちょうど使う

window.parent

iframeに呼び出しフレーム/ウィンドウを取得します。複数の呼び出しフレームがある場合は、使用できます

window.top

3

これを試して、親フレームで次のようなIFRAMEを設定してください。

<iframe id="frame1" src="inner.html#frame1"></iframe>
<iframe id="frame2" src="inner.html#frame2"></iframe>
<iframe id="frame3" src="inner.html#frame3"></iframe>

各フレームのIDは、srcのアンカーとして渡されることに注意してください。

次に、内部のhtmlで、location.hashを介して読み込まれたフレームのIDにアクセスできます。

<button onclick="alert('I am frame: ' + location.hash.substr(1))">Who Am I?</button>

次に、parent.document.getElementById()にアクセスして、iframe内からiframeタグにアクセスできます。


はい、これは最も論理的な解決策ですが、場合によってはiframeのsrcを変更する必要があります。このハッシュまたはGETパラメータを各リクエストに渡すことは適切ではありません。
JoséLeal

毎回ハッシュを渡すのが悪いのはなぜですか?サーバーではなくブラウザにのみ表示され、getパラメータのようにキャッシュに影響を与えることはありません。
マークポーター、

-1
// just in case some one is searching for a solution
function get_parent_frame_dom_element(win)
{
    win = (win || window);
    var parentJQuery = window.parent.jQuery;
    var ifrms = parentJQuery("iframe.upload_iframe");
    for (var i = 0; i < ifrms.length; i++)
    {
        if (ifrms[i].contentDocument === win.document)
            return ifrms[i];
    }
    return null;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.