7cc@はてなブログ

JavaScriptとかとか

スムーズスクロールの「戻る」を正常化する JavaScript

1.history.pushStateが使える場合

それで解決。IE10以上のすべてで使える。
*移動後に location.replace("#" + target.id) でハッシュを活性化?しないとtarget疑似クラスが有効にならないのでそれだけ注意。
location.hash = target.idだとGChromeで:targetが有効にならないのでreplaceでハッシュ更新すること。

2.使えない場合

ハッシュに存在しないidを付与してやる

var target = document.getElementById("id")
location.hash = "0" // idに指定してはダメなもの
target.scrollIntoView() // スクロール処理
location.replace("#" + target.id)

存在しない要素のハッシュをつけるのがいやなら追加してやればよい。ただし、position: fixedはIE-Quirksでは無効なのでonscrollかページ内リンククリック時にtop,leftをその時点のpageYOffset,XOffsetに合わせる。

if(!document.getElementById("0")) {
  var e = document.createElement("div")
  e.id = "0"
  e.style.cssText = "position: fixed; top: 0; left: 0"

  document.body.appendChild(e)
  location.hash = "#0"
}

そもそもなぜできないのか

移動先の要素(の近く)でハッシュを更新しているため。以下のコードが戻れない移動法。

var target = document.getElementById("id")
target.scrollIntoView()
location.hash = "id"