トップ回答者
javascript で location.href の書換えと submit

質問
-
※ WinXP/IE6 や Win7/IE9などで確認(おそらくOSやブラウザに依存しないと思いますが)。JavaScript の関数内で、フレームのurlを書き換えてブランク画面にする処理を実行後、直ぐに該当するフレームをターゲットにしたsubmitを実行します(実際の動作はファイルアップロード)。
submitに時間がかかる場合、ブランク画面となって欲しいのですが、ブランク画面とならずsubmitからのレスポンスがあるまで実行前の内容が表示されたままです。
対処としては、frame1 の内容を直接書き換える等で可能かと思いますが、(質問)
location.href の書換え後 submit による location の書換え(?)により、「location.href の書換えによる動作」が行われないという、javasciprt か ブラウザの仕様によるものでしょうか?
※ 別のフォーラムで「location.href の書換えによって、ナビゲーションが発生しますが、その処理は非同期なので、当然」との返信をいただきました。
非同期の問題ではないとの認識がありましたので、また、こちらのフォーラムの方が良いとの、ご意見をいただきましたので、再質問をしています。
---処理イメージ---function f1() {
frame1.location.href = "about:blank";
form1.submit();
}
---html---
<form name="p1" enctype="multipart/form-data" method="post" action="cgi" target="frame1">
<input type="file" name="f1">
</form>
<iframe name="frame1" target="frame1" src="~~"></iframe>
回答
-
その質問文の意味が不明なんですけど。
javascriptの仕様とか言ってるのは、javascriptが何で出てくるのかわからない、javascriptの言語仕様は関係ないし、location.hrefへの代入操作の仕様とかという意味ですか?
ブラウザの仕様というのは、ブラウザの実装という意味ですか?
要するに、仕様か、実装か、という質問ですか?
そういう意味なら(´・ω・`)さんが先に言ってるようにnot specifiedで、後者でしょう。と、いう事で OK ?
- 編集済み ウィンドウズスクリプトプログラマ 2013年7月24日 9:45 記事補足
- 回答としてマーク 多山 真一 2013年7月24日 12:23
-
返信いただいた方々、ありがとうございます。
調査していく中で確認できた事実:
function f1() {
frame1.location.href = "a.html";
frame1.location.href = "b.html";
frame1.location.href = "c.html";
}
こんなことを実行してみると(IE9の[ツール]-[開発者ツール]-[ネットワーク]で確認したところ)
a.html のリクエストが発生 => ただし、リクエストは[保留]
b.html のリクエストが発生 => a.html のリクエストは[中断]、b.html のリクエストは[保留]
c.html のリクエストが発生 => b.html のリクエストは[中断]、最終的に、c.html が画面に表示される。
※ c.html に対してのリクエストだけかと思っていたが、ちょっとビックリ!
※ Chrome だと c.html だけしか実行されない(ただし、ツールの表示だけでそのように見せているだけかも知れませんが...)。
想定される動作:
通信などの処理(location書換え)は直ぐに実行される/実行しようとする。(submit実行直後の[保留]状態となっていたので、おそらく同様と思われる)
画面表示は処理が完了後に最終状態のものだけが表示される。
これだけでは、同期・非同期などは厳密にはわかりませんが、以降も、事実か想定の情報がわかっていくことがあっても、「javasciprt か ブラウザの仕様によるものでしょうか?」は、わからないものと判断します。
質問そのものが、明確ではなく、ご迷惑をおかけしましたが、ひとまず、質問した者としてはクローズとさせていただきます。
- 回答としてマーク 多山 真一 2013年7月24日 12:24
すべての返信
-
※ 別のフォーラムで「location.href の書換えによって、ナビゲーションが発生しますが、その処理は非同期なので、当然」との返信をいただきました。
「非同期の問題ではない」というのはどういう意味でしょうか? 同期処理が行われているとお考えでしょうか? もし href に指定したURLがhttpであれば、ネットワークから取得後、表示完了(onloadなども実行完了)後に次の行 form1.submit() に進むとお考えなのでしょうか?
非同期の問題ではないとの認識がありましたので、また、こちらのフォーラムの方が良いとの、ご意見をいただきましたので、再質問をしています。 -
※ 別のフォーラムで「location.href の書換えによって、ナビゲーションが発生しますが、その処理は非同期なので、当然」との返信をいただきました。
「非同期の問題ではない」というのはどういう意味でしょうか? 同期処理が行われているとお考えでしょうか? もし href に指定したURLがhttpであれば、ネットワークから取得後、表示完了(onloadなども実行完了)後に次の行 form1.submit() に進むとお考えなのでしょうか?
非同期の問題ではないとの認識がありましたので、また、こちらのフォーラムの方が良いとの、ご意見をいただきましたので、再質問をしています。同期や非同期の話ではなく、それ以前の仕様の話かと考えております。
記載した JavaScript の関数では、href の書換え後、直ぐに、書き換えた フレームを TARGET にした submit を実行しており、そもそも、href の書換えが、無かったことにされているのではないかとの想定をしております。
そのように考える理由は、JavaScript での操作が完了した後(ブラウザに制御が戻ってから)にブラウザが描画処理を開始するとに認識があります。そのため、描画する必要が無い書換えを無かったことにしているのでは?と考えています。
※ 念のため、明日にでも、"about:blank"以外の有効のアドレスで通信が発生するか確認しておきます。
-
ちょっと別の話題になってしまいますが、 IMG要素のonloadイベントについて という記事を書いたことがあります。
img.srcの設定後にimg.onloadを設定するとonloadイベントが発生しないことがあります。これはバグでもなんでもなくonloadイベントの設定前にimg.srcの読み込みが完了してしまっていてonloadイベントは不要と判断されてしまう動作です。これと同じことが言えるのではないでしょうか? ページ遷移は非同期に行われるものであり、JavaScriptの関数終了後に行われるわけではない、と。
- 回答の候補に設定 佐祐理 2013年7月24日 13:22
-
たとえて言うと、VBAのDoEventsが必要なのでは。
function f1() {
frame1.location.href = "about:blank";
form1.submit();
}でなく、
function f1() {
frame1.location.href = "about:blank";
setTimeout("f2()",100);
}function f2() {
form1.submit();
}提示ありがとうございます。
こちらでも、ブラウザに一度制御を戻す、この方法で、画面がブランクになることは確認できています。
その他、frame1.document.body.innerText = "" など、直接表示内容を消去するなどでも実現はできています。
質問の意図としては「javasciprt か ブラウザの仕様によるものでしょうか?」、また、同期や非同期に動作によるものか?などの、できれば技術的な情報がわかればと質問させていただきました。
-
スクリプト操作した内容を反映させるには、一旦ブラウザに制御を戻さないと反映されない。
確かに、このような当然のことは仕様のどこかに記載されているように思えますね。
PeekMessage()等の非同期向けAPIをのぞいて
JavaScript処理というのはGUIスレッドと同期して処理が行われるのは仕様で定義されているのではないか?
ただ、フレームをまたがった場合は裏で通信がされて反映されても良さそうだし、そもそもブラウザに制御を戻した後であるため、うまく表示される可能性があり、その部分を話題にしている。
と解釈いたしました。
仕様に無いんでしたっけ?
参考程度に今思ったことを書かせていただきますと、
ちょうど話に出た「画像」を例にすると、これをGUIを設計する際は、Proxyパターンを用いて枠だけを表示しておき、別途裏で通信すると都合がよさそうに思えます。実際そのように動作しているように見える事象がある。
同じように「ウィンドウ」についても、GUIを設計する際は、Proxyパターンを用いて枠だけを表示しておき、別途裏で通信すると都合がよさそうに思えます。
一方、submit()の方は、同期的に動作するイメージをしています。
上記の想定のとおり裏でとってきた可能性の高いと考えるabout:blankは反映を待ち受けている状態になっているのかもしれませんね。
フレームを管理するWindowProxyオブジェクトの仕様を確認してみても、どうやら変数空間の単位であって表示の同期性については触れられていないようです。 http://d.hatena.ne.jp/cou929_la/20110310/1299767973
- 編集済み (´・ω・`) 2013年7月24日 7:20 動作の補足の修正
-
frame1.location.href = "about:blank";
setTimeout("f2()",100);試した感じでは、urlによって時間は変わるようです。about:blankなら短くてもよいでしょうが、それでもシステム負荷などによっては足りないことがないとはいえないでしょう。非同期とはそういうものです。
一般のurlでは、
URL が書き換わったか判定すればいいのでは、、、
と試しに IE10 の URL に about:blank と入力した後に javascript:alert(location.href) とした場合に拾えない事から、IE の問題なのかもしれません。
- 編集済み ウィンドウズスクリプトプログラマ 2013年7月24日 4:52 記事追加
-
その質問文の意味が不明なんですけど。
javascriptの仕様とか言ってるのは、javascriptが何で出てくるのかわからない、javascriptの言語仕様は関係ないし、location.hrefへの代入操作の仕様とかという意味ですか?
ブラウザの仕様というのは、ブラウザの実装という意味ですか?
要するに、仕様か、実装か、という質問ですか?
そういう意味なら(´・ω・`)さんが先に言ってるようにnot specifiedで、後者でしょう。と、いう事で OK ?
- 編集済み ウィンドウズスクリプトプログラマ 2013年7月24日 9:45 記事補足
- 回答としてマーク 多山 真一 2013年7月24日 12:23
-
返信いただいた方々、ありがとうございます。
調査していく中で確認できた事実:
function f1() {
frame1.location.href = "a.html";
frame1.location.href = "b.html";
frame1.location.href = "c.html";
}
こんなことを実行してみると(IE9の[ツール]-[開発者ツール]-[ネットワーク]で確認したところ)
a.html のリクエストが発生 => ただし、リクエストは[保留]
b.html のリクエストが発生 => a.html のリクエストは[中断]、b.html のリクエストは[保留]
c.html のリクエストが発生 => b.html のリクエストは[中断]、最終的に、c.html が画面に表示される。
※ c.html に対してのリクエストだけかと思っていたが、ちょっとビックリ!
※ Chrome だと c.html だけしか実行されない(ただし、ツールの表示だけでそのように見せているだけかも知れませんが...)。
想定される動作:
通信などの処理(location書換え)は直ぐに実行される/実行しようとする。(submit実行直後の[保留]状態となっていたので、おそらく同様と思われる)
画面表示は処理が完了後に最終状態のものだけが表示される。
これだけでは、同期・非同期などは厳密にはわかりませんが、以降も、事実か想定の情報がわかっていくことがあっても、「javasciprt か ブラウザの仕様によるものでしょうか?」は、わからないものと判断します。
質問そのものが、明確ではなく、ご迷惑をおかけしましたが、ひとまず、質問した者としてはクローズとさせていただきます。
- 回答としてマーク 多山 真一 2013年7月24日 12:24
-
一般的には、iframeのdomはセキュリティで触れないこともあるので、
2つのiframeを交互にdisplay:noneで切り替えて、targetしますね。
相手がシングルでぐずぐずしてるなら、こっちで多重化しちゃう。
- 編集済み ウィンドウズスクリプトプログラマ 2013年7月24日 14:40 誤字訂正