Weblasts

Scrollifyを使わずセクションごとにスナップするスクロール制御を自作

セクション(ブロック)ごとのスクロール制御をして欲しいと依頼を受け、背徳感を感じながら初めてのスクロールハイジャックをしてみました

よくある形として1ページごとめくるようにスクロール制御できるように各セクション(ブロック)の高さはビューポートと同じ(100vh)にして制御するかと思いますが、
依頼されたものはビューポートからはみ出るようなセクション(ブロック)も混ざっていたので「Scrollify.js」を使用することにしてみました

セクション(ブロック)ごとにスクロールを制御できるjQueryのプラグイン「Scrollify.js」を使ったサイトはPC表示ではちらほら見ますが、大体の場合スマートフォンでの表示時はその機能を解除しているケースが殆んどです。

なんとなく「Scrollify.js」を触ってみて気づいたスマートフォンで使われていない理由としては

  • 動作が安定しない
  • ビューポートよりも高いサイズのセクション(ブロック)内のスクロールも画面ごとスクロールされる制御になる
  • スマートフォンのステータスバーをタップしたときの挙動がおかしくなる

上記の理由から自分も了解を得てスマートフォンでは「Scrollify.js」を解除して実装しましたが、どうにかならんものかということでちょっくら勉強ついでに自作してみました。

ちなみにCSSでスクロールスナップを実装できる「scroll-snap-type」を試してみようかな?と思いましたがアニメーションの種類や時間の指定が柔軟に指定できなかったりするので使いにくかったりしたので使いませんでした

スナップするスクロールのデモとベース

まずはデモページ
ステータスバーをタップしたときの機能をなくしたくて色々調べた結果こんな感じになりました

サンプルのHTML

サンプルのHTMLは以下の通りでコンテンツ全体を.wrapで囲んでいます
.blockがスナップする要素になっています

jQueryの準備

今回イージングの設定が楽になるのでオワコンの呼び声高いjQueryを使います
こちらをhead要素内で読み込んでいきつつ、イージングの種類を増やすためeasing.js(今回使ったもののバージョンは1.3)も読み込んでおきます。

初期から用意されているイージングで十分であれば必要はないですが一応以下にDLリンクを用意しています

※ iPhone用のステータスバー絡みを制御するmetaタグがいろいろなところで紹介されていますが入れても効果がないようなので入れなくてもいいと思います。

head要素は以下のようになっています

サンプルのcss

ステータスバーをタップしたときの効果が出ないようにするため、body要素の高さをビューポートサイズに固定しておきます

.wrapもビューポートサイズに固定しつつ、内包した要素をスクロールして見ることができるようにしています。
ここの「position:fixed」はなくても大丈夫なのですが、なにかのミスで.wrapの外に要素ができてしまったときに位置がずれるのを防ぐための保険としてつけています

heightやmin-heightで使っているdvhの単位は対応していないブラウザもあるかもなのでvhと二重で指定しておくといいと思います

Intersection Observer APIを利用し実装

普通にscrollイベントを使って実装しようと思ったけれどObserverを使うと便利そうな感じだったのでこちらで実装してみました。

Intersection Observerに関しては下の記事でまとめてあります

以下のをscript要素にいれbody要素の閉じタグの手前にごっそり入れて上げれば完成

細かい説明は時間があるときに追記します

てか、なんでスクロールハイジャックなんだ?スクロールジャックならわかるけど

コメント部分がおかしかったらごめんなさい

PROFILE

フリーランスでweb系のデザイン・コーディング&プログラミングをしています

youtubeはじめました