Motomichi Works Blog

モトミチワークスブログです。その日学習したことについて書いている日記みたいなものです。

JavaScript学習日記 その0005 ブラウザバック時の挙動と対策について考えてみる

参考にさせて頂いたページ

まずa.htmlとb.htmlを作成する

a.html

a.htmlはbody内に以下のように記述しました。 フィールドのvalueにdefaultを入れています。 submitするとgetでb.htmlへ遷移します。

フィールドを編集してからsubmitして、b.htmlからブラウザバックしたときのイベント発火とフィールドのvalueについて検証してみます。

<h1>Page a</h1>

<form action="b.html">
  <input type="text" name="example" value="default">
  <input type="submit" value="送信">
</form>

<script>

alert('hoge');

window.onload = function(){
  alert('window.onload');
};

window.onpageshow = function(){
  alert('window.onpageshow');
};
</script>

b.html

b.htmlはbody内に以下のように記述しました。 ただh1タグがあるだけです。

<h1>Page b</h1>

今日の検証環境

Windows10の2017年4月15日現在の以下のブラウザで試しています。

a.htmlでフィールドをeditedに変更してsubmitしたあとブラウザバックしてみる

alertが実行される場合は〇、ブラウザバックしたときにフィールドのvalueは編集を保持しているかは以下の通りでした。

ブラウザ hoge window.onload window.onpageshow value
Chrome edited
Firefox × × edited
IE edited
Edge edited

a.htmlでフィールドをeditedに変更してページを更新してみる

submitせずに更新してみるパターンです。 ページ更新なのでalertは全て実行されますが、FirefoxIE、Edgeはページを一度更新してもvalueにeditedが残りました。 そのままもう一度更新すると、IEとEdgeはdefaultに戻り、Firefoxは何度更新してもeditedが残りました。 一度目の更新のあとで、残っているeditedをそのままにしてsubmitしたとき、パラメータはもちろんb.html?example=editedですが、もう一度ブラウザバックするとIEとEdgeではvalueはdefaultに戻りました。 さすがにフォーム入力途中でページ更新はイレギュラーな行動だと思いますが。

ブラウザ hoge window.onload window.onpageshow value
Chrome default
Firefox edited
IE edited ※一度だけ保持
Edge edited ※一度だけ保持

a.htmlにwindow.onunload = function(){};を記述してみる

追記して以下のようにしました。

<h1>Page a</h1>

<form action="b.html">
  <input type="text" name="example" value="default">
  <input type="submit" value="送信">
</form>

<script>
window.onunload = function(){};

alert('hoge');

window.onload = function(){
  alert('window.onload');
};

window.onpageshow = function(){
  alert('window.onpageshow');
};
</script>

Firefoxでブラウザバックしたときにhogeとwindow.onloadのalertが実行されるようになりました。 window.onunload = function(){};を書くことで、ブラウザバック時に各alert()の実行と、編集したvalueにeditedが残るというように、4つのブラウザで同じ結果を得られるようでした。 ただ、何度更新してもvalueの編集内容が保持されるFirefoxについてはどうしたものかと思います。

ブラウザ hoge window.onload window.onpageshow value
Chrome edited
Firefox edited
IE edited ※一度だけ保持
Edge edited ※一度だけ保持

jsでテキストを変更してからsubmitして、ブラウザバックしてみる

たとえばbuttonタグを配置して、以下のようなjQueryのコードを書きます。

$(function(){
  $('button').click(function(){
    $(this).text('clicked');
    $('[name="example"]').val('clicked');
  });
});

buttonをクリックして、テキストとvalueがclickedに変わったあと、submitしてブラウザバックしたときFirefoxでは以下のようになります。

  • window.onunload = function(){};が記述されていないa.htmlではclickedが保持されました。
  • window.onunload = function(){};が記述されているa.htmlではtext()で変更した箇所は元に戻っていましたが、val()で入力したvalueはあくまでもフィールドの入力値なので保持されました。

ChromeIE、Edgeではwindow.onunload = function(){};を書いても書かなくても、ブラウザバックしたときのテキストはbuttonに戻っていて、valueはclickedを保持していました。

おわりに

Macの標準的なブラウザであるSafariを試せていません。

MaciOSAndroidを試せていませんが。

対応としてはwindow.onunload = function(){};を記述して以下のような状態にするのが多くの場合第一候補な気がしました。

  • フォームの入力値はユーザの変更を保持
  • jQueryvalueを入力した箇所はフォームの入力値なのでclickedを保持
  • jQueryでのテキスト変更は無かったことにする

ということになるようでした。