背景
JavaScriptでsmooth scrollを実装してほしいという依頼を受けました。そのサイトはあるASPを利用していて、なにかをインストールするということはできません。
方法を探す
JavaScript初心者のわたしはとりあえずググることにしました。すると、スムーズスクロールを実装しようとしている人なら誰もが見ていそうなページが見つかりました。
素のJavaScriptで実装したかったので、このページに書かれているwindow.scrollToを使う方法でいこうと思います。
実装
ざっと実装してみました。
1 | const buffer = 50; |
scroll_triggerというidを付与したaタグにスクロールのイベントリスナーをセットします。そのほか、いくつかのブラウザのAPIを利用しています。
element.getBoundingClientRect
ドキュメントにあるように、width と height 以外のプロパティは、ビューポートの左上を基準としていますので、ページ内の現在の表示箇所によって返ってくる値は異なります。(ビューポートの左上より下にあればプラスの値、上にあればマイナスの値)
window.pageYOffset
こちらもドキュメントにあるように、現在のビューポートがページの一番上からどれくらいスクロールしているかを表します。pageYOffsetはscrollYのエイリアスだそうです。
そして、今この文章を書いていて気付いたのですが、
1 | const top = scrollTargetTop + offsetTop - buffer; |
は常に同じ値を返すので(当たり前ですか?w)、addEventListenerの中で毎回計算する必要はありませんでした…
window.scrollTo
scrollToはドキュメントの構文にあるように、2種類の引数をとります。
1 | window.scrollTo(x-coord, y-coord) |
今回利用しているのは引数にoptionsをとる方です。optionsはこちらで定義されています。今回はtopとbehaviorを指定しています。
IEで動作させたい
現状のままでは、IEで動作しませんでした…IEでも動作させたいので、手を入れていきます。
scrollToの引数を変える
先ほど書いた通りwindow.scrollToの引数は2種類あって、IEはオブジェクトではない方であれば、スクロールするということで、やってみました。
1 | window.scrollTo(0, top); |
すると、スムーズスクロールではなく、その位置に移動する動作になってしまいました。これでは最低限の役目は果たしているもののイマイチです。
polyfillの導入
今回一番勉強になったのがこちらです。最初に紹介したスムーズスクロールを紹介していたページに記載されていましたが、npm installしていたので見過ごしていました。npm installせずとも利用できました。
polyfillとは?
MDN Web Docsにはなんでもありますね…ドキュメントにあるように、最近の機能をサポートしていない古いブラウザーで、その機能を使えるようにするためのコードです
polyfillを利用する
https://polyfill.io/v3/url-builder/で利用したい機能のチェックボックスにチェックを入れます。今回はsmoothscrollにチェックを入れます。すると、画面上部にURLが表示されます。copy url to clipboardをクリックしコピーします。
今回のURLは
https://polyfill.io/v3/polyfill.min.js?features=smoothscroll
です。これを<script>で読み込みます。
1 | <script src="https://polyfill.io/v3/polyfill.min.js?features=smoothscroll"></script> |
この1行を一番最初に書いたJavaScriptの上に追加します。そしてIEで試してみると、スムーズスクロールできていました。
まとめ
JavaScript初心者のわたしがスムーズスクロールを実装するまでを記しました。JavaScript初心者はまずブラウザAPIを正しく理解することが重要だと思いました。MDN Web Docsのドキュメントをちゃんと読むべきですね。
JavaScriptの言語仕様を学ぶのであれば、JavaScript Primerを読みましょう。この本はとてもわかりやすく書かれていて、プログラミングの用語についてもわかりやすく説明してくれています(プリミティブ、リテラルなど)
IEで動作しない場合はpolyfillを最初に調べましょう。1行足すだけでIE対応ができるかもしれません。