log > メニューを通り過ぎると、上部に固定するメニュー

参考資料とほとんど同じなので詳細は省く。違う場所は、jQueryを使わずに実装するところ。動作確認はChrome53とFirefox48でしかしてない。スマホは非対応。

See the Pen gwLoNX by deprode (@deprode) on CodePen.

scrollTop、scrollLeft

scrollTopとscrollLeftはスクロール量を取得するプロパティ。このコードではそれぞれ

document.documentElement.scrollTop || document.body.scrollTop
document.documentElement.scrollLeft || document.body.scrollLeft

で取得してる。

もうちょい厳密にやる場合は、window.pageYOffset || documentElement.scrollTop || body.scrollTop || 0;でいいし、jQueryと同じにしたい場合はこのように実装すればいい。

offset

Element.getBoundingClientRectは左上を0,0とした表示領域の座標が取得できるメソッドで、左上からの座標とスクロール量を合わせた値がoffsetになる。つまり、getBoundingClientRectとscrollTop(scrollLeft)を合わせた値がoffset。

getBoundingClientRectをサポートしてないブラウザはほぼ現存していないので、その辺のコードを省いた。(元のコードはgetBoundingClientRectが存在しないとjQueryでoffsetを取得しているが、jQueryを使わないコードだとoffsetを取得するためにoffsetを取得することになるので無理だし、最新のjQueryではgetBoundingClientRectでoffsetを取得してるから、getBoundingClientRectが取得できないという想定が非標準的っぽい。)

addClass、removeClass

Element.classListを使用しているが、IE10以上でサポートしている。なので、IE9はサポートしてない。IE9をサポートする場合は、素直にjQueryを使ったり、eligrey/classList.jsのようなpolyfillを使った方がいい。

その他

<header>が高さ固定でメニューを内包しているので問題になってないが、そうでない場合はスクロールするとメニューをposition: fixedにするとずれる。そのため、同じメニューを置いてfixedと切り替えて表示するなどが必要だった。

参考資料