Ajaxでページの表示内容が変更された状態でリンクをクリックして違うページに行った後ブラウザバックで戻ると前ページがajaxで更新された状態ではなく初期状態になってしまっているのをどうにかしたいとあれこれ調べてやってみた話です。
history.pushStateはページ遷移があると無意味
「ajax ブラウザバック」で検索すると出てくるhistory.pushStateですがこれはページ遷移があると使えません。
私も最初よくわからないまま使ってみていろいろ試してみたんですが、ブラウザバックで発火するpopstateイベントはページ遷移時は発火しません。
これはajaxでの更新履歴をhistory.pushStateで残してそれをブラウザバックでたどれるようにしている機能のようなので「ページ遷移はajaxじゃないから知らん」ってことなんだと思います。
「history.pushState」と「popstateイベント」はページ遷移しない状態でのajaxの更新履歴をブラウザバックで戻るときに使うもの、ということで移動した先のページから戻るときにはまったく使えないということです。
ブラウザバックを検知するイベントが無い
残念ながらどうやらブラウザバック時に発生するイベントは無いようです。
いろいろと調べた結果ブラウザバックでも確実に発火するイベントはpageshowのみらしいです(参考:Qiita ▷ ブラウザバックでのページ表示時処理)。
ところがpageshowはタイミングが遅い!!!
ページの表示物の内容にもよるけど場合によっては発火までかなり時間がかかることがあります。
ブラウザバックを検知するイベントが無い以上pageshowを使うしか選択肢が無いわけですがどうにも納得できないですね。。
参考にしてみた記事
上記の2点を理解したうえで最善の解決策と思われるのがこちらの記事。
この記事を参考に自分のサイトで試してみました。
ページ遷移のブラウザバックもpageshowで対応できるし、history.pushStateでajaxの更新履歴もたどれる。完璧。
と思ったんですがなんとなく「パラメータ使うの嫌だなぁ」というのと、自分のサイトではhistory.pushStateで履歴をたどる必要性がまったく感じられなかったのでやめました。
もう一つ試した記事がこちら
記事の下の方にtextareaを使ったやり方が紹介されています。
なるほど入力フォームのタグは確かにブラウザバックで戻っても入力内容が残りますね。頭良いなぁ。
結論:Ajaxは入力フォームで作れ
ということで上の2つの記事を試してみた結果、ajaxで使うものは全部入力フォームで作っておくのが一番簡単で安全な方法なんだろうという結論になりました。
タブなどで表示内容を変えるならタブをラジオボタンで作る。
ページ番号なんかもラジオボタンで作る。
表示を変更したものはtextarea(非表示)に残しておいてpageshowイベント時に書き換える。
これならブラウザバックでページを戻してもすべて残っているので復元可能です。
ただpageshowが遅いのがなぁ。。