- 締切済み
入れ子のフレームでjavascriptが上手く動作しない
frame.html ----- フレームセットを設定している frm1.html ------ フレーム1に表示する frm2_a.html ---- フレーム2に最初に表示する frm3_a.html ---- フレーム3に最初に表示する frm2_b.html ---- フレーム2に二番目に表示する frm3_b.html ---- フレーム3に二番目に表示する jscript.js ----- 外部javascript frame.html(抜粋) <head> <script type="text/javascript" src="jscript.js"></script> </head> <frameset cols="*, 200px"> <frameset rows="*, 100px"> <frame src="frm1.html" name="フレーム1" onload="addHtml()" noresize> <frame src="frm2_a.html" name="フレーム2" noresize> </frameset> <frame src="frm3_a.html" name="フレーム3" noresize> <noframes> </noframes> </frameset> jscript.js(抜粋) function addHtml(){ alert("in"); parent.フレーム2.location.href = "frm2_b.html"; parent.フレーム3.location.href = "frm3_b.html"; parent.フレーム3.document.getElementById("addArea").innerHTML = "追加内容"; alert("out"); return; } frm3_b.html(抜粋) <body> <div id="addArea"><div> </body> frm.htmlをブラウザ(IE系)で表示 → onloadイベントでaddHtml() → フレーム切り替え、"追加内容"をaddAreaに追加 → 追加されず、alert("out")の行が実行されない。 更新ボタンを押し、alert("in")をOKボタンで消し、 次のalert("out")のダイアログを表示している間だけ追加された内容が表示され、 OKボタンで消すとaddArea内の内容が消えます。 フレーム1にページが読み込まれたときにイベントでスクリプトを 動かしたいのですが、うまくいかずこまっています。 問題点や改善点、別のやり方等教えていただけないでしょうか。 不明な点がございましたら、訂正・補足いたします。 よろしくおねがいします。
- みんなの回答 (8)
- 専門家の回答
みんなの回答
- arexis
- ベストアンサー率66% (66/99)
#6は#5を読んでない時点なのでalert()ついてます。 またフレーム2にも書き込むケースがあるとの事でそれも付加して ■frame.html <head> <script type="text/javascript" src="jscript.js"></script> </head> <frameset cols="*, 200px"> <frameset rows="*, 100px"> <frame src="frm1.html" name="frame1" onload="addHtml()" noresize> <frame src="frm2_a.html" name="frame2" onload="L.f2 = true" noresize> </frameset> <frame src="frm3_a.html" name="frame3" onload="L.f3 = true" noresize> <noframes> </noframes> </frameset> ■jscript.js if(!self.L){ var L = {}; } window.onload = function(){ L.first = true; addHtml(); } function addHtml(){ if(!L.first) return false; L.f2 = false; frame2.location.href = "frm2_b.html"; L.re2 = 0; addf2() L.f3 = false; frame3.location.href = "frm3_b.html"; L.re3 = 0; addf3() } function addf3(){ if(L.f3){ frame3.document.getElementById("addArea").innerHTML = "追加内容3"; }else{ if(L.re3 <100){ L.re3++; setTimeout("addf3()",50); } else{ /* タイムアウト処理が必要ならココ */ } } } function addf2(){ if(L.f2){ frame2.document.getElementById("addArea").innerHTML = "追加内容2"; }else{ if(L.re2 <100){ L.re2++; setTimeout("addf2()",50); } else{ /* タイムアウト処理が必要ならココ */ } } } ロード確認のチェック用変数と無限回避の変数などが増えますのでそれもまとめてしまって 他のスクリプト部分の変数とぶつからないようにグローバルで使用するのは L だけにしてます。
- leap_day
- ベストアンサー率60% (338/561)
こんにちは >リンク先拝見しましたが、ちょっと私の考えている使い方ではありませんでした。 同じ関数内に入れたり、連続で処理させるとload時のタイミングが分からない(処理と読み込みが同時に行われる)のでリンク先のを応用して別ページのfunctionを呼び出してやる・・・という意味でしたが考えに合いませんでしたか? 書いてるうちに新しい補足が入ったのでそちらのもとりあえず併用します 『frame段組ページ(frame.html)』 <script type="text/javascript"><!-- URL = new Array( "http://***/frm1.html", "http://***/frm2_b.html", "http://***/frm3_b.html", "http://***/frm4.html", "http://***/frm5.html", "http://***/frm6.html" ); function addHtml() { if(frame1.location.href == URL[0]) { frame2.location.href = URL[1]; frame3.location.href = URL[2]; } if(frame1.location.href == URL[3]) { frame2.location.href = URL[4]; frame3.location.href = URL[5]; } } function add() { if(frame1.location.href == URL[0] && frame3.location.href == URL[2]) { alert("in") frame3.document.getElementById("addArea").innerHTML = "追加内容"; alert("out"); frame3.document.getElementById("addArea").style.display = "none"; } } //--></script> <frameset cols="*, 200px"> <frameset rows="*, 100px"> <frame src="frm1.html" name="frame1" id="frame1" onload="addHtml()" noresize> <frame src="frm2_a.html" name="frame2" id="frame2" noresize> </frameset> <frame src="frm3_a.html" name="frame3" id="frame3" noresize> <noframes> </noframes> </frameset> 『追加ページ(frm3_b.html』 <script type="text/javascript"><!-- window.onload=function() { parent.add(); } //--></script> <div id="addArea"></div>
- arexis
- ベストアンサー率66% (66/99)
とりあえず理解力が乏しいせいか混乱してきてます。 ■frame.html <head> <script type="text/javascript" src="jscript.js"></script> </head> <frameset cols="*, 200px"> <frameset rows="*, 100px"> <frame src="frm1.html" name="frame1" onload="addHtml()" noresize> <frame src="frm2_a.html" name="frame2" noresize> </frameset> <frame src="frm3_a.html" name="frame3" onload="f3Loaded = true" noresize> <noframes> </noframes> </frameset> ■jscript window.onload = function(){ first = true; addHtml(); } function addHtml(){ if(!self.first) return false; self.f3Loaded = false; alert("in"); frame2.location.href = "frm2_b.html"; frame3.location.href = "frm3_b.html"; addtext() } var repeat = 0; function addtext(){ if(parent.f3Loaded){ frame3.document.getElementById("addArea").innerHTML = "追加内容"; alert('out'); frame3.document.getElementById("addArea").innerHTML = ""; //消す? 消さないなら不要 }else{ if(repeat <100){ repeat++; setTimeout("addtext()",50); } else{ /* タイムアウト処理が必要ならココ */ } } } これで目的に沿いますか? ^^; やり方の問題なのかonloadを後から受付てくれないので、ちょっと確認用変数入れてます。
- arexis
- ベストアンサー率66% (66/99)
私が理解不足だったのと、それでもちょっと理解できない部分があるので補足お願いします。 動作順序について frm1.htmlが読み込まれる ↓ alert('in')が表示されてる間だけ、フレーム2,3には最初のページ(_a)が表示されていて、アラートを消すと、フレーム2,3に(_b)が表示される。と言う事ですか? この場合alert('out')の意味は? それともalert('in')の間だけ、フレーム2,3には(_b)が表示されていて、alert('out')が消されるとフレーム2,3は(_a)に戻すのですか? また、フレーム1にfrm1.html以外の別のページが読み込まれたときも、常に同じ(_b)がフレーム2,3に表示されるんですか? その辺の流れを書いてください。
- arexis
- ベストアンサー率66% (66/99)
えっと、 まず一番最初の時点ではフレーム2,3は変更無くフレーム定義のままのページで、 『何らかの操作』でフレーム1が変更された時に、2,3が連動して変ると言う事ですね? それならフレーム定義ファイルframe.htmlにはjavascriptは書かずに フレーム1に表示される初期ページ以外に書けば良いと思いますよ。 フレーム1に表示されるページが自分のページではない場合なら、 フレーム1を変更する『何らかの操作』の部分でjavascriptを動かしておけば良いかと。 あとIEだけでよいのですかね? No1に書いた物は破棄してください。 ブラウザの違いもとりあえず気にしないで済む方法として ■frame.html <head> </head> <frameset cols="*, 200px"> <frameset rows="*, 100px"> <frame src="frm1.html" name="frame1" noresize> <frame src="frm2_a.html" name="frame2" noresize> </frameset> <frame src="frm3_a.html" name="frame3" onload="f3Loaded = true" noresize> <noframes> </noframes> </frameset> ■frm1_b.html (フレーム1の初期ページ以外) <script> window.onload = function(){ parent.f3Loaded = false; parent.frame2.location.href = "frm2_b.html"; parent.frame3.location.href = "frm3_b.html"; addtext() } var repeat = 0; function addtext(){ if(parent.f3Loaded){ parent.frame3.document.getElementById("addArea").innerHTML = "追加内容"; }else{ if(repeat <100){ repeat++; setTimeout("addtext()",50); } else{ /* タイムアウト処理が必要ならココ */ } } } </script> こんなかんじでフレーム3がきちんと読み込まれてから書き込めると思います。 ベタな方法だと思いますけど^^; >>私の書いたものの場合はフレーム2の内容が変更される前に変更後にしか存在しない要素に対してアクセスしているということでしょうか? 変更前にアクセスしてるわけじゃなくてLoading中でしょうね。 多分ですが、自ドキュメント内に読み込まれているスクリプトならロード中でも対象があれば書き込めて有効ですが、外から書き込む場合は対象があって一度書き込んでもロード完了前の物は破棄されてしまうと思います。 なのでalert()などで流れを止めて途中経過をみると書き込めていても、最終段階で破棄されてるのでは?と。 外からの場合は必ずロード完了を確認してから実行しないとって事です。
お礼
わからない部分があるのですが frm1_b.htmlにスクリプトを書いておられますが それだと、frm1_b.htmlを読み込まないと実行されませんよね? 初回表示時にframe1(frm1.html読み込み時)のonloadで実行したいと思っていたのですが。 補足事項ですが、frame1(フレーム1)のページを変更するのは frame1に表示されるページからのみです。 frame2(フレーム2)やframe3(フレーム3)からは frame1のページを変更させるような操作はしません。 ブラウザはIEのみを想定していただいて結構です。 私が使っているブラウザはSleipnirですが。
- SAYKA
- ベストアンサー率34% (944/2776)
><frame src="frm1.html" name="フレーム1" onload="addHtml()" noresize> 原因はここ 単純に「フレーム1」だけがonloadになったら駆動しているのが問題。 これは極端な話、このframe.htmlが完全にloadされていないのにフレーム1 だけがonloadしてしまう可能性が有り、その場合フレーム2・フレーム3が描画も定義もされてなくてdocument木に出現しないので動作しない、という状態になるよ。 この場合で有効なのは「全てload完了」を他のframeのonloadを含めた方法で感知させる必要があるね。 でも状況からしたらfrm2_a.htmlとfrm3_a.htmlにbに切り替わるscript書いた方が早いんじゃないかとか思った。
お礼
具体的な指摘ありがとうございます。 描画の順番までは考えが及びませんでした。 これからは注意して組んでいきたいと思います。
- leap_day
- ベストアンサー率60% (338/561)
こんにちは ※テキスト追加は面倒だったので別の方法でやっています こういうのを応用すればできると思いますが・・・ http://www.openspc2.org/reibun/javascript/frame/010/index.html parentは子画面から親画面を指定するときに使うので(今回だとフレーム内のページ(frm1.html,frm2_a.htmlなど)からフレーム段組み(frm.html)に対して使用します ですので今回の場合document.で十分対応できます 流れ的には フレームページ(frm1.html,frm2_a.html,frm3_a.html)を初め表示し、 frm1.htmlロード完了後alert("in"); フレーム3に『追加内容』を表示 alert("out"); フレーム2にfrm2_b.html,フレーム3にfrm3_b.htmlを表示 ということでいいのですよね? <script type="text/javascript"><!-- function addHtml() { alert("in"); document.getElementById("frame2").src="frm2_b.html"; frame3.document.open(); frame3.document.write("追加内容"); frame3.document.close(); alert("out"); document.getElementById("frame3").src="frm3_b.html"; } //--></script> <frameset cols="*, 200px"> <frameset rows="*, 100px"> <frame src="frm1.html" name="frame1" id="frame1" onload="addHtml()" noresize> <frame src="frm2_a.html" name="frame2" id="frame2" noresize> </frameset> <frame src="frm3_a.html" name="frame3" id="frame3" noresize> <noframes> </noframes> </frameset> ※リロード時のことは考えていません(><) リロード時にもfrm1.html,frm2_a.html,frm3_a.htmlを表示するならwindow.onload=function(){ }などで対応させてください
お礼
回答ありがとうございます。 リンク先拝見しましたが、ちょっと私の考えている使い方ではありませんでした。 回答いただいたスクリプトですが このやり方で問題なく動作しますがframe3が丸々書き代わってしまうので 私のやりたいこととは少し異なります。 frm3_b.htmlの内容は残しつつ、内容を追加したいのです。 ありがとうございました。
- arexis
- ベストアンサー率66% (66/99)
とりあえずの対処なら ■frame.html のフレーム3にonload="addinner()" をつけて <frame src="frm3_a.html" name="フレーム3" onload="addinner()" noresize> ■jscript.js function addHtml(){ alert("in"); parent.フレーム2.location.href = "frm2_b.html"; parent.フレーム3.location.href = "frm3_b.html"; alert("out"); return; } function addinner(){ parent.フレーム3.document.getElementById("addArea").innerHTML = "追加内容"; } これで一応表示もできて、エラーはでにくくなると思います。 これでもでちゃう時ありますけど。 フレームもウィンドウオープンも、ドキュメントがロードされたかを確認してからアクセスしないとエラーだらけになると思います。 nameを日本語にしてるのは外人対策かなにかで、わざとですか?
補足
回答ありがとうございます。 私の説明が足りないところがありましたので補足します。 ◎フレーム1のページが変更された時のみスクリプト動作 フレーム2や3は変更されず、フレーム1のみが変更される場合があります。 フレーム2や3が変更されても、フレーム1が変更されない場合は動作させない。 >>・・・ロードされたかを確認してから・・・ ということは、私の書いたものの場合はフレーム2の内容が変更される前に 変更後にしか存在しない要素に対してアクセスしているということでしょうか? (addAreaはfrm_a.htmlになく、frm_b.htmlにしかない。 frm_bに変更される前にまだ存在しないaddAreaにアクセスしている?) ちなみに、nameが日本語なのはその方がわかりやすいかなと思ったからです^^; 実際はすべて違うnameなり関数名で、わかりやすい名前に変更したのです。 しかし、冷静にみればフレームのnameだけ日本語て変ですね。。。 質問をした時は焦っていたので、頭が回りませんでした orz 普通ならframe1,2,3としますかね、今から変えるとややこしいので 特に訂正はしないことにします。(もちろん変えて頂いても結構です)
補足
alert("in"),alert("out")に意味はありません。 単にスクリプトの動作を確かめるためとここでの質問のためにかきました。 なので、最終的にはjscript.jsに書きません。 フレーム1に別のページが読み込まれたときに同じページが表示されるとは限りません。 その分岐はaddHtml()で判別します。 読み込まれたページのファイル名を取得して、それにより処理を分岐させます。 addHtml(){ switch(読み込んだページのファイル名){ case frm1_a: 処理A; break; case frm1_b: 処理B; break; } } というような感じです。(あくまでイメージなので実際のものとは異なります。) 処理AやBはフレーム2や3のページにHTMLを追加する処理です。 私がやりたいのは フレーム1にページが読み込まれる ↓ addHtml()が作動 ↓ フレーム2、3に読み込まれている(はずの)ページの addAreaなどにHTML("追加内容")を追加 ↓ 正常に表示(元のHTMLに"追加内容"が追加されたHTMLが表示され、次の操作を受け付ける) です。 こういった説明でよろしいでしょうか? 不明な点があれば、申しつけください。