0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

(2015年時点の古い記事になってしまいましたが、もったいなかったので公開します)

Firefoxで「戻る」と「戻りすぎる」という謎現象に出逢ったので、それについてのメモ。

結論から言うと、firefoxの正常な謎仕様です。setTimeoutでぶった斬りましょう。

現象

  • バナー表示を行う
  • バナーのリンクをクリックした時にJSONPでサーバと通信
  • サーバでの処理完了を待って、location.hrefに値を入れてページ遷移

という処理を行っていました。

その状況で、firefoxでだけ、遷移後に「戻る」と、バナー表示を行ったページが飛ばされて、それより前に表示されていたページに戻る...つまり、戻りすぎるという現象が発生しました。

詳しくブラウザの表示履歴を見ると、バナークリックで遷移した後、バナー表示を行ったページの履歴が残っていない状態でした。

仕様のこと

ページがloading状態の時に、location.hrefで遷移した場合、そのページを「履歴に残さない」という仕様があるようです。location.replaceの動作になるイメージですね。ただ、location.assignもこの条件ではreplaceと同様の動作になるようです。

古き悪しきlocation.hrefでのリダイレクト実装への対処を行うための仕様..のように思われますが、詳細は不明です。

Firefoxはこの仕様を妙に厳格にとるのか、2015年の今日、ver42でも発生しています。

この実証コードでは、hashbangで動作を再現できるようになっています。(fails in firefox)と書かれた項目のリンクをクリックすると#done_4になりますが、「戻る」と、#start_4になりません。

対処のこと、内部の動作のこと

実証コードのページに対処法も載っています。setTimeoutを使う方法ですね。

察するに...

JSONPの通信後、レスポンスのjsファイルから、コールバック用のメソッドが呼ばれて、レスポンス後の処理に入ります。このとき、jqueryのajaxコマンドに渡すsuccesメソッドに処理を書きますが、どうやらこれが、「jsファイルの地の文」の処理の流れから直接実行されているようです。

「jsファイル読み込み→jsファイルの地の文の実行→実行完了」までが読み込み処理とみなされるため、successメソッドで直接location.hrefを書き換えると、「読み込み処理中のページ遷移」とみなされます。

そこで、location.hrefの書き換えをsetTimeout(func, 0)の中で行うようにすると、それを呼び出した(読み込み中の)処理の流れから切り離されるので、「読み込み完了後」に遷移が発生したことになり、履歴は無事残るようになる...

ということらしい。

何故にJSONPの読み込みが、一度読み込み完了したはずのページ全体の「読み込み中」を引き起こすのかは若干納得がいきませんが...

まとめ

  • firefoxには、JSONPのコールバックでlocation.hrefを書き換えると、履歴が意図せずに消える謎仕様がある
  • JSONPのコールバック内でページ遷移を起こしたい場合は、setTimeoutを使って処理を切る

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?