ie でページ遷移時に location.hash 通りの表示位置にならない件について

2年ほど前に同じ事で悩んでドキュメントに残しておかなかったので、最近また同じ事で悩んでしまったので書いておこうと思います。まぁそもそも元の実装方法が悪いのが原因なのでアレなんだけど、ソレはソレで業務アプリ側を変更できない部分なので仕方がない・・・という余計な前置きはさておいて・・・

例えば登録系の処理で入力ミスがある場合、フォーム箇所まで表示位置をスクロールさせた状態でページ遷移をさせたい要件を考えます。単純に考えて http://localhost/hoge.cgi#name1 のように form の action 先の location.hash をよろしく設定すると思います。

通常なら何も問題なく location.hash の値に従ってアンカー名が検索され表示位置が補正(移動)されてページ遷移しますが、ie でアクセスした場合に限り、location.hash に従ってブラウザのエンジンが画面スクロールを処理している最中(だと思う・・・)に alert() のような描画を一旦停止させるような javascript を実行させると画面のスクロールを途中で止めてしまうようです。

結論から話すと、対処方法としては javascript は wondow.onload を利用するか、ソースの一番下に script タグを書いて画面描画を終えた後に実行するようにせよ!ってだけなんです。まぁ基本って言っちゃぁ〜基本なんですけどね・・・(;^_^A

と書いても、何を言っているのかよくわからないのでサンプルをもとに説明していきます。

- スポンサーリンク -

画面の構成は以下の図のようになっています。
location.hash によって指定の場所にスクロールした状態でのページ遷移を想定したサンプルです。検証のため、あえて javascript のソースを html ソースの真ん中らへんに記述して、画面描画が一旦停止するように alert() による警告ダイアログを表示させています。

img01.png

※実際の html へはこちらからアクセスできます。なるべくウィンドウサイズを縦に小さくして実行してみて下さい。

まずは初期状態。

img02.png

次に [alertなし] jump_point_1(#L1)へ をクリックした状態。このときは正常に表示位置がアンカー名 L1 まで移動する。

img03.png

top を押して初期状態に戻ってから [alertあり] jump_point_1(#C1)へ をクリックした状態。このときはスクロール処理中に警告ダイアログが表示されて描画停止するため ie では正常に表示位置がアンカー名 C1 まで移動できない。

img04.png

top を押して初期状態に戻ってから [alertあり(timer)] jump_point_1(#R1)へ をクリックした状態。このときは警告ダイアログの表示を setTimeout 関数で 0.1 秒後にしているため、スクロール処理が終わってから警告ダイアログが表示される。その結果 ie でも正常に表示位置がアンカー名 R1 まで移動できる。

img05.png

top を押して初期状態に戻ってから3種類の jump_point_2 のをクリックした状態。script タグの下に記述された html は script タグを実行した後に解析され描画処理される。従って警告ダイアログを表示有無にかかわらず、指定のアンカー名まで正常に表示位置が移動する。

img06.png

まぁ結論を先に書きましたが、script タグが一番下に書かれていればこのような不具合は発生しません。html の途中に script タグを書きたいなら window.onload とか使って html を全て処理した後に script の処理を実行させるようにした方がいいってことですね。

ちなみに ie 以外のブラウザでは、警告ダイアログで [OK] を押した後に画面描画処理が続行され、指定のアンカー名の場所まで正常に表示位置が移動します。ie 独自仕様ですかね?これも。

- スポンサーリンク -