iframe 内から親ページの要素にアクセスする方法

HTML5 では iframe の機能強化が行なわれています。

例えばサンドボックス (sandbox) も実装され、スクリプトの実行権限やフォームサブミットの制御なども行なえるようになりました。

Android で言うところのフラグメント的に使え、再利用も簡単なので今後はより利用が進むものと思われます。

しかし、プログラミングを行なうにあたっては、少し注意が必要になります。

なぜなら、あるページ A 上の iframe 内にロードされた ページ B では、ドキュメントが異なるためです。

ページ A から B は、iframe 自体が A 上にあるのでアクセスは簡単ですが、特にページ B から A を参照するには少し工夫が必要です。

ここでは次のシナリオをどのように実装するのか説明します。

ページ iframe-test.html 内に iframe があります。その iframe の src には iframe1.html が設定されています。そして、iframe1.html 上にはボタンがあります。

このボタンを押したときに、親ページである iframe-test.html の p タグ内に、文字 "Hello!" を設定しています。

これはどのように実装したらよいでしょうか。

iframe-test.html は次の通りです。

<!DOCTYPE html>
<html>
    <head>
        <style>
        #f1 {
        width: 250px;
        height: 100px;
        border: 1px solid #aaa;
        }
        </style>
    </head>
    <body>
        <iframe 
          id='f1' 
          name='f1' 
          src='iframe1.html'></iframe>
        <p id='p1'></p>
    </body>
</html>

iframe1.html は次の通り。jQuery の取り込み箇所は//code.jquery.com/jquery-1.12.4.min.jsを指定しています。

<!DOCTYPE html>
<html>
    <head>
        <script src="..."></script>
        <script src='iframe1.js'></script>
        <style>
        body {
            background-color: #ccc;
        }
        </style>
    </head>
    <body>
        <p><button id='button1'>TEST</button></p>
    </body>
</html>

さて、問題の iframe1.html に読み込まれる iframe1.js は次の通りです。

$(document).ready(function(event){
  $('#button1').click(function(event){
    $('#p1', parent.document).text('Hello!');
  });
});

ポイントは iframe1.html から、その親ページの要素にアクセスするときに、親ウィンドウのドキュメントを取得している点です。 現在のウィンドウの親ウィンドウは parent で取得できます。従って親ウィンドウのドキュメントは parent.document で取得できます。

同じドキュメント内の要素はコンテキストを指定せずに $('#p1') などとして取得できますが、今回は parent.document から要素を探すので、 $('#p1', parent.document) としています。