フレーム間の変数の値の受け渡しについて
フレーム間の変数の値の受け渡しについて
前回の投稿では、フレームを利用した場合の、親フレームと子フレームの関係で動きを試しました。
今回は、一つのフレームに子フレームが複数ある場合、
その子フレーム間での変数の値がどのように取得できるのかを試してみます。
前回の投稿と同じ、以下のようなHTMLを用意します。
(便宜上jquery.jsを読み込んでいますが、必須ではありません)
まず、各フレームをまとめるtest.htmlを一つ
<html> <head> <title>フレーム使用例</title> <script src="./jquery.js"></script> <script src="./main.js"></script> </head> <frameset rows="150,*"> <frame id="frm1" name="frm1" src="test1.html"> <frameset cols="250,*"> <frame id="frm2" name="frm2" src="test2.html"> <frame id="frm3" name="frm3" src="test3.html"> </frameset> <noframes> このページはフレームを使用しています。 </noframes> </frameset> </html>
それと、
各フレームのhtmlファイル
test1.html test2.html test3.html
test1.html、test2.html、test3.html
はそれぞれ親フレームから呼ばれる子画面のHTMLです。
それぞれのhtmlファイルは以下のように書きました。わかりやすいように内容はほぼ同一で、画面表示時にアラート出力をしています。(最終的な検証では削除します)
test1.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>test window1</title> <script src="./jquery.js"></script> </head> <body> <script type="text/javascript"> alert("クライアントサイドjs 1"); var test1 = "aaa"; alert(window.test1); </script> test 1 </body> </html>
test2.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>test window2</title> <script src="./jquery.js"></script> </head> <body> <script type="text/javascript"> alert("クライアントサイドjs 2"); //ここでtest1.html内の変数にアクセスしている alert(parent.frm1.test1); </script> test 2 </body> </html>
test3.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>test window3</title> <script src="./jquery.js"></script> </head> <body> <script type="text/javascript"> alert("クライアントサイドjs 3"); </script> test 3 </body> </html>
ここまでのファイルを準備して、各ファイルにjavascriptを埋め込んで動作を確かめてみます。
まず、test1.htmlのjavascript内に、以下のように変数を代入します。
let test1 = "aaa";
次に、このtest1.htmlで代入した変数を、test2.html内で読み込んでアラート表示してみます。
test2.html
alert(parent.frm1.test1);
ここまでで、ブラウザからtest.htmlにアクセスすると、
ダイアログがtest1.htmlの読み込みで2回、test2.htmlの読み込みで2回、test3.htmlの読み込みで1回、表示されます。
ポイントとなる点は、test1.htmlで格納した変数に、test2.htmlからアクセスしている点です。
test2.htmlから
parent.frm1.test1
という書き方をして、フレームごしのtest1.htmlに代入した変数にアクセスしています。
ところが、最近のjavascriptの変数の宣言はletで書くことが主流といえるので、
試しにletで書いてみたところ、test2.htmlのダイアログ出力ではundefinedが表示されました。
これはletで宣言した変数にフレーム間で呼び出すことができないスコープが存在していることと言えます。
実際にサーバ上に設置したhtmlは以下のURLで確認できます。
https://propansystem.net/blogsample/js/015/
フレームをまたぐ関数の受け渡しについて
次に、フレーム間で変数を受け渡すのではなく、関数を宣言して受け渡してみます。
先ほどと同様に、test1.html、test2.html、test3.htmlを用意し、
test1.html内に関数を宣言します。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>test window1</title> <script src="./jquery.js"></script> </head> <body> <script type="text/javascript"> function test1func() { alert("test1func"); } </script> test 1 </body> </html>
次に、test2.htmlで、test1.htmlで定義した関数を呼び出します。
test2.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>test window2</title> <script src="./jquery.js"></script> </head> <body> <script type="text/javascript"> alert("test2 start !"); parent.frm1.test1func(); </script> test 2 </body> </html>
こうすることで、test2.htmlからフレームごしのtest1.htmlに書かれた関数「test1func」を呼ぶことができます。
この時に注意する点としては、
・関数をフレームごしに呼ぶ場合は、スコープに注意する。
・関数内でグローバル変数を参照すると、「関数を書いた側」のフレームのプロパティが検索される。
・ユーザ定義関数とは別に、javascriptがもともと定義されている関数を呼び出す場合は、コンストラクタとコンストラクタのプロトタイプオブジェクトは、フレームごとに別々に持っている。
という点になります。
ただ、ここは詳しく実装して検証してみないとイメージしずらいので、
別な投稿としてとりあげたいと思います。