ブラウザの戻ると進むを無理やり判別する
- かなり無理やり
- pushStateが使えない環境での話
- スムーズスクロールの戻る/進むを正常化するだけなら
スムーズスクロールについて無駄に考えてみたメモ のTest4, Test5を参照してください。ここに書いてある方法は無理やりです。
背景
多くのスムーズスクロールはスクロール後にハッシュを付与しているのでブラウザの「戻る」が動かない。そこで戻る」を可能にする方法を考えた・・・が無理やりな方法になってしまった。
「戻る」だけなら問題ないが、その後「進む」をする可能性があるので「進む」も考える必要があったのだ。
例えばページ内を #a -># b -> #a -> 戻 と移動したとする。このときハッシュは#bになり、進んでも戻っても次は#aになる。これを判別する手は思いつかない。
その無理やりな方法
そこで、ハッシュを追加することで一応判別できるようにした。具体的には
- ページ内リンクをクリックしたら#0, #1をつける
- 要素へ移動する
- 移動後に本来のハッシュをつける
- 「戻る」ならハッシュは#1, 「進む」ならハッシュは#0になる。やったね…?
無理やりゆえの欠点
- onhashcange イベントが無駄に起こらないように注意がいる
- history.lengthが加算されるのでページから抜けられなくなる可能性がある
- history.lengthは最大値がある。Firefoxで50まで。それ以降は増えない。
- location.hashの変更時にはidがあるか調べられているのでその分の負荷がかかる
無理やりなコード
var inpageLinks = document.querySelectorAll("a[href^='#']") // add Events for (var i=0, l=inpageLinks.length; i<l; i++) { inpageLinks[i].addEventListener("click", cl, false) } window.addEventListener("hashchange", ha, false) // functions var count = 0 function cl(){ location.hash = "0" location.hash = "1" return count = 0 } function ha(){ console.log(count++) if(count > 3) { inpageHistoryBackForward() return count = 3 } } function inpageHistoryBackForward() { if(location.hash === "#0") { history.go(2) } else if(location.hash === "#1"){ history.go(-2) } }