フレーム間の変数の値の受け渡しについて
フレーム間の変数の値の受け渡しについて
前回の投稿では、フレームを利用した場合の、親フレームと子フレームの関係で動きを試しました。
今回は、一つのフレームに子フレームが複数ある場合、
その子フレーム間での変数の値がどのように取得できるのかを試してみます。
前回の投稿と同じ、以下のような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がもともと定義されている関数を呼び出す場合は、コンストラクタとコンストラクタのプロトタイプオブジェクトは、フレームごとに別々に持っている。
という点になります。
ただ、ここは詳しく実装して検証してみないとイメージしずらいので、
別な投稿としてとりあげたいと思います。