jquery.inviewを使わずにjquery.inviewのような事がしたい
最近、社内で「jquery.inviewが便利で手放せぬ」という話を聞きまして、便利で手軽なプラグインは本当にありがたいものであります。
しかしjqueryをこのためだけに読み込まないといけない、という絶妙にずっと残っている論争があるのも事実です。
自分個人としましては、なるべくjqueryが無くても良いようにしていこうと意識しているところではありますが、人それぞれ、じゃあバニラなjsで書こうとなれる人となれない人がいて、そしてそれが良いも悪いもないという、ちょっと難しい時代です。
ということで、「jquery.inviewプラグインみたいな動き」をさせる方法を2つ紹介してみたいと思います。
求められる結果
- スクロールして
.js-show
要素が指定の位置に来たら、.is-active
クラスが付与される - 1回だけ発火する
上記2点を目指してやってみたいと思います。
1.Intersection Observer APIを使用してみる
【Intersection Observer APIとは】
rootになる要素とtargetになる要素が交差したかどうかを監視してくれるAPI。
なに?となるかもしれませんが、画面(rootになる要素)の中に、特定の要素(targetになる要素)が入ってきたかどうかを監視してくれる、という考え方で良いそうです。
【実装】
早速やってみます。
結論としてはこうなります。(更新する場合はRerunをクリックしてください)
【ポイント】
-
1回発火したら監視を停止
クラスが付与されるのは1回だけで良い場合は、ここで監視を止めておくと不要な監視を減らせます。スクロールするたびに付与したい場合は適宜削除してください。
observer.unobserve(entry.target); // 一度発火したら監視を停止(クラスを削除する場合は不要)
【オプションの「root:」「rootMargin:」「threshold:」プロパティについて】
「root:」
targetになる要素があるかどうか監視している大枠、rootになる要素のことです。
とくに指定されていない場合はビューポートになります。
指定方法:null
または、特定の要素の指定もできます。
null
の場合
「rootMargin:」
rootになる要素に対して指定するプロパティです。
rootになる要素の範囲を拡大、縮小させて交差するタイミングを調整できます。
rootMargin: 'top right bottom left'
指定方法:’0px 20%’
、というようなcssのmarginプロパティのように指定できます。(単位が必須らしいのでpxや%を必ずつけます)
rootMargin: '0px'
、threshold: 0
の場合
rootMargin: '-20% 0px'
、threshold: 0
の場合
rootMargin: '20%'
、threshold: 0
の場合
「threshold:」
targetになる要素に対して指定するプロパティです。
targetになる要素の領域が何%交差した時に発火するか、の調整ができます。
threshold: 0
指定方法:0
、というような0〜1の数字で指定。(0.5で50%となる)
rootMargin: '0px'
、threshold: 0.5
の場合
rootMargin: '0px'
、threshold: 0.5
の場合
2. GSAPを使用してみる
GSAPを使用するならクラス付与せずそのままアニメーションをつければ良いのでは?と思われるかもしれませんが、今回は忘れていただけますと幸いです。
クラス付与もできると知っておくと、なにかと助かったりするのです。
【GSAPとは】
JavaScriptのアニメーションライブラリ。
※ライセンスについて、現在は「サイトを利用するうえでエンドユーザーが料金を支払う必要がある場合」には有料ライセンスが必要となるようです。通常のサイトで使用する分には問題ありませんので、しっかり大丈夫かどうか事前に確認が必要です。
ライセンスについて:https://gsap.com/licensing/
【実装】
早速やってみます。
結論としてはこうなります。(更新する場合はRerunをクリックしてください)
【ポイント】
-
once: true
のオプションで1回だけ実行するように設定スクロールするたびに付与したい場合は適宜削除してください。
once: true, // 1回だけ実行
-
markers: true
は、GSAPに用意されている確認用のオプション公開時に削除するのを忘れないようにしてください。
markers: true, // デバッグ用のマーカーを表示
【オプションの「markers:」「start:」プロパティについて】
「markers:」
確認用のマーカーが表示されるようになります。
これが大変ありがたいものでして、scroller-startの位置に、targetになる要素のstart位置が重なったら発火する様子も確認できます。
指定方法:true
でマーカー表示。デフォルトはfalseとなっているので不要であればプロパティごと削除しましょう。
「start:」
クラスを付与するタイミングを調整できます。
前述で紹介したmarkers:プロパティをtrue
にしておくと確認しやすくなります。
start: 'target位置 ビューポート位置'
-
target位置
: targetになる要素のどこを基準にするか -
ビューポート位置
: ビューポート(画面)のどこを基準にするか
指定方法:'top 80%'
、'bottom 80%'
、'50% 50%'
、'top bottom-=50'
など
start: 'top 80%'
の場合
start: 'top 80%'
の場合
あとはcssで
クラス付与の仕組みができたので、あとはopacityやtransformでいい感じに調整しましょう。
どちらが良いのか?
単純にクラスを付与するだけで良いのであれば、「Intersection Observer」の方がお手軽かなと思いますが、クラスを付与するだけでなくいろいろなアニメーションを実装する場合は、GSAPの方ができることが多いです。
どちらも便利で良いですね!!(用途と内容に応じて試してみてください!)
まとめ
jquery.inviewの手軽さに比べると、やはりコードも増えてしまいますし理解に時間がかかると感じるかもしれません。
ですが、様々な方法で同じようなことができることを知っておくと、大変困ってしまった時の自分や周りの人を助けてあげられるかもしれません。これはとても良いことなのではないかなと個人的に思います。
今ならAIに良い方法は無いかと聞いてみると教えてくれるので、これでいい場合もあるかもしれないですね。
スクロールしたらなにか動く、表示させる、という動きの実装は本当にとてもとてもよくあります。
今はもう当たり前になってしまいましたが、しかしいつ頃から流行りだしたのでしょうか。インターネットさんはすごいスピードで変わっていくので頑張って追いついていきたいと思います。
最後まで読んでいただき、ありがとうございました。
Discussion