なんか難しくって忘れそうなのでメモっておきます。
history.pushState(state, title, url)
履歴に指定したURLを追加するってこと。指定したURLへの再読み込みは発生しないので、読み込みの処理は自分で行う。
hoge.com
のページでhoge.com/hoge
にしたい場合
history.pushState(null,null,"/hoge");
こうするとブラウザのURL欄がhoge.com/hogeに変わる。けどページには何も変化が起こらない。
pushStateするとブラウザのURL履歴が追加される。わかりやすく説明すると
history.pushState(null,null,"/hoge1");
history.pushState(null,null,"/hoge2");
history.pushState(null,null,"/hoge3");
このように履歴を3回追加したあとに、ブラウザの戻るボタンをクリックしていくと
"hoge.com/hoge3"->"hoge.com/hoge2"->"hoge.com/hoge1"-> "hoge.com"
の順に、ブラウザのURL欄が変わっていきます。このときやはりページの内容は変わりません。
さらにhoge.com
まで戻った後にブラウザの進むボタンをクリックすると
"hoge.com"->"hoge.com/hoge1"->"hoge.com/hoge2"-> "hoge.com/hoge3"
の順に、ブラウザのURL欄が変わっていきます。
しつこいようですが、ページの内容は変わりません。
history.repalceState(state, title, url)
現在の履歴が書き換えられます
要は履歴に追加されないってこと。
hoge.com
の状態で下記を実行すると
history.relpaceState(null,null,"/hoge1");
アドレス欄がhoge.com/hoge1
に変わりますが、ブラウザの戻るボタンを押しても
一つ前のhoge.com
には戻りません。hoge.comを見ていた前の履歴のアドレスが表示されます。
見た目の履歴上は、hoge.comには行っていないことになります。
もうサルでもわかるように説明すると。(サルな自分に説明すると・・)
history.pushState(null,null,"/hoge1"); //ブラウザのURL欄はhoge.com/hoge1
history.pushState(null,null,"/hoge2");//ブラウザのURL欄はhoge.com/hoge2
history.replaceState(null,null,"/hoge3");//ブラウザのURL欄はhoge.com/hoge3
history.pushState(null,null,"/hoge4");//ブラウザのURL欄はhoge.com/hoge4
このように3回目にreplaceStateを実行したとします。
さて、ブラウザの戻るボタンを押すとどうなるでしょう?
現在のURLは hoge.com/hoge4です。
1回目 ブラウザのURL欄はhoge.com/hoge3 になります。
2回目 ブラウザのURL欄はhoge.com/hoge1 になります。
というわけでhoge2には行っていないように見えます。
今度は進むボタンを押すと
html
現在のURLは hoge.com/hoge1です。
1回目 ブラウザのURL欄はhoge.com/hoge3 になります。
2回目 ブラウザのURL欄はhoge.com/hoge4 になります。
このようにhoge2は出てきません。
第一引数State
ここまでnullで無視してきた第一引数ですが、これはなんでしょうか?
検索すると
履歴に関連付する任意のオブジェクトを渡すことができ、そのオブジェクトはpopstateイベントハンドラから参照することができます。
????
サルでもわかるよう解説すると(サルな自分に・・・)
window.onpopstate=function(e)
console.log(e.state);
}
//現在のURLはhoge.com
history.pushState("hello",null,"/hoge1");
この状態でブラウザの戻る、進むボタンを押してみてください。
進むボタンを押した後に、ブラウザのコンソールで見ると
helloと表示されると思います。stateは、こんな感じでページ遷移時のイベントハンドラに渡されます。また、history.stateでもアクセスできます。
詳しくは下で解説
popState
これで最後。
これはpushState後にブラウザの戻る、進むを行った場合のイベント取得するために使用します。
前述の通り、pushStateや、pushState後の戻る、進むボタンではページ内容が
変わりませんでしたよね。
pushStateの場合、pushStateを実行したときにページを読み込む処理を書けばよいですが、
ブラウザの戻るや進むボタンを使った場合には、このpopStateイベントで捕まえて
ページを書き換える必要があるわけです
//本当はwindow読み込み時に処理するけど省略
window.onpopstate=function(e){
どこの解説にも書いてあるので一応いれとく
if (!e.originalEvent.state) return; // 初回アクセス時に再読み込みしてしまう対策
//ページ読み込み、描画処理
・・・・
}
こんな感じですかね。
ちなみに現在のパスはlocation.pathname
、クエリはlocation.search
なんかで取得できあすので、これを使って現在のURL応じたページ描画処理を行います。
あと、ブラウザの戻る、進むをjavascirptで処理する場合は
戻る:history.back()
進む:history.forward()
を使います。
これらの関数呼び出し後も同様に、popStateイベントが発生します。
※HTML5以降の実装なので、古いブラウザだと使えません。
以上、自分はこれでだいたい理解しました。