Ajaxのサーバとクライアントを実装する際の基礎事項(ブラウザバック対応)を検討する なお,このページの内容はIE(Internet Explorer 6)で検証したものです.他のブラウザでは動作が異なる可能性があるので注意してください.
ことの発端Ajax化したBugTrackを動かしていて気づいたのだが,BugTrackの画面から別の画面に遷移して,そこからブラウザバックでまたBugTrackに戻ってくると,スクロールバーが一番下にあるわけでもないのに,先読み処理が実行されてしまう.動きを細かく調べたところ,先読み処理の判断に使っているhidden値が,処理のタイミングで本来の値になっていないのが原因だった. Alertを入れて調べたところ,ブラウザバックで戻ってきたときには,画面のhidden値は以下のように変化していた.
そのため,一覧にどれだけ行を追加した状態であっても,ブラウザバックで戻ってきてJavaScriptの処理が走るときはまだ(1)の状態なので,初期のhidden値に合わせた処理が行われてしまい,最初と同じ処理を繰り返してしまうという話だった. このあたりの内容について整理したので,以下に書きます...
ブラウザバック時の画面内容について別のページに遷移してブラウザバックで戻ると,そのページが再描画される. このとき,直前まで表示していた内容がそのまま表示されるのが普通である. 確かにHTMLでページが構成されている場合はそのようになるが, しかしAjaxでinnerHTML属性にHTMLを注入して画面を構築している場合は,そうならない.
そしてブラウザバックで戻ると, ページの内容は初期状態に戻ってしまう.innerHTMLに注入した内容は失われる これは閲覧者にとっては結構腹が立つので,何か対策が必要.
画面内容が最初に戻らないための対策画面が最初の状態の戻るのを防ぐために,画面を構築するのに必要な情報を,hiddenに保持しておく.hiddenに保持しておけば, ブラウザバックしたときには,直前に見ていたときの内容でhidden値は復元されるので, それを使って,innerHTMLの注入(画面の構築)をやり直せばよい. まとめると,
という処理を行うことにした. これによって,ブラウザバックで戻ってもページにはさっきまで出ていた内容が表示されている, という状態になるはず.
画面の構築をすべきタイミングの詳細上で,ページのbodyがonLoadされた後もしくはそれに準ずるタイミング と書いたが,要は,ある程度「遅い」タイミングである. 具体的にどう実装するかについて,以下で考える.
(a) body内で実行する (NG)<body> ・・・ <script type="text/javascript"> // ここでhiddenを参照して画面の構築をする </script> ・・・ </body>
(b) body.onLoadイベントで実行する (OK)<body onLoad='reDraw()'> ・・・ <script type="text/javascript"> function reDraw() { // ここでhiddenを参照して画面の構築をする } </script> ・・・ </body>
(c) body内からタイマーを使って実行する (微妙)<body> ・・・ <script type="text/javascript"> window.setTimeout("reDraw()", 1000); // 1秒後にreDraw()を呼び出す function reDraw() { // ここでhiddenを参照して画面の構築をする } </script> ・・・ </body> しかし,確信は持てない. setTimeout()での「1秒後」という設定には,何の根拠もない. 結局,(b)のbody.onLoad方式が理想だが,何らかの事情でonLoadイベントをカスタマイズできない場合は, 次善の策として(c)のタイマー方式を使うという感じ. ただしタイマー方式は本当にあてにならないので,それでも支障がない場合にしか使えない. (といいつつ,カモランドでは使っています)
hidden以外に記録する案上記のような微妙なタイミングの問題を回避するために,hidden以外に記録できないかと考えたが,以下のように駄目だった.
JavaScriptのグローバル変数に入れる案JavaScriptのグローバル変数に入れると,ブラウザバックすると値が消えてしまった→ 駄目
クッキーに入れる案セッションクッキーに入れる方法を試したところ,クッキーに保存してもそれを読み込めないという現象が発生した.色々試してみたところ,保存サイズが大きいと駄目だった.例えば以下のサイトによると,約4〜5KB程度までしか保存できないとのこと.
ということで,カモランドの用途では,クッキー方式はサイズの制限が厳しくて使い物にならなかった. |