jQuery があってもなくても動く inview.js のようなプラグインを作ってみた

JavaScript

アロー関数などの台頭により IE が切り捨てられつつある今、jQuery 3.0 以外を使う機会はあまりありません。さらに 3系未満では脆弱性の問題が確認されたと JVN が発表しています。

最近では IE のサポートをマイクロソフトが終了するとのこともあり、僕は積極的に jQuery 3 系を使用してきました。このブログは WordPress で作成されていますが、 WordPress 標準の1系ではなく、わざわざ3系を使っていたりします。

スポンサーリンク

inview.js は jQuery 3.x 系では動かない

久しぶりに「要素がユーザの画面内に入ったらふわっと上がってくる演出」を作る機会があったので、inview.js を使ってみることに。

が、どうしてか inview が動作しません。コンソールにエラーもなし。困りました。

これは調査が大変そうかなあと思いましたが、よくよく考えてみれば心当たりがありました。 inview.js は5年以上も前に更新が止まっている jQuery ライブラリです。

もしかして jQuery のバージョンが問題なのでは、と思いました。

これがまさしくそのとおりで、jQuery のバージョンを一時的に 1.8.0にしてみたところ、 inview が正しく動作しました。ちなみに2.0.0でも動きません。

jquery.inview.js のようなライブラリの自作

幸い jQuery のバージョンを 1.8.0 に落としても動かなくなる部分は現れませんでしたが、冒頭の脆弱性の問題もありますし、そもそも jQuery 1.x 系は IE 8 以前をサポートするためのバージョンです。

今更そこまで互換性を保つ必要性は感じられないので、できれば jQuery 3.x 以上のままやりたいことを演出したい!

そう思った僕はこの機能を自作することにしました。

出来上がったものは github で配布しています。

Releases というリンクから zip をダウンロードできます。(直接ソースコードを開いてコピペしてもらっても構いません)

intersectAction.js か、または intersectAction.min.js をダウンロードして HTML 内で読み込んで使ってください。

inview.js との違い

使い方自体は Readme に記載しているのでそれを読んでもらうとして、この記事では inview.js での書き方と intersectAction.js での書き方を比較したりして inview.js との違いを説明します。

交差交差って書いてあるけど交差ってなんぞや

一つ混乱をふせぐために説明しておきます。

そもそも前提として inviewでは「画面に入ったら」という表現を使いますが、この intersectAction では「特定の要素と交差したら」という表現を使っています。intersect も交差という意味の英単語です。

デフォルトではユーザが見ている画面と交差したら処理が発火します。

これは intersectAction で「画面に入ったら」という判定に IntersectionObserver という 機能を使っているからです。よくわからない人は「交差交差言ってるのは画面に入ったらという意味なんだな」と思っておいてください。

実際に使ってみているコードを比較して使い方を確認

要素に isShow というクラスを付与する処理を書いてみます。

// jquery.inview.js

$('.fadeIn').on('inview', function(){
  $(this).addClass('isShow');
})

inview.js では、「画面から見えなくなったら」という処理が必要ない場合、if を書く必要はありません。ですが、intersectAction.js では 「交差していない場合~」という処理が必要ない場合でも if 文が必要です。

// intersectAction.js

intersectAction($('.fadeIn'), function(element, isIntersecting){
  if(isIntersecting){
    element.addClass('isShow');
  }
})

また、inview の場合、渡したい関数に引数がない場合でも動作しますが、intersectAction は必ず2つの引数を渡す必要があります。

第一引数が $(this) の代わりとなり、第二引数が交差しているかどうかの判定に使われるからです。

そして inview との決定的な違いは、jQuery がなくても動くということです。

const fadeIn = document.getElementsByClassName('fadeIn'); // HTMLCollection
// const fadeIn = document.querySelectorAll('.fadeIn'); // NodeList を渡しても OK
intersectAction(fadeIn, function(element, isIntersecting){
  if(isIntersecting){
    element.classList.add('isShow');
  }
})

jQuery オブジェクトを渡された場合は jQuery としての振る舞いをするので、 addClass が使えます。しかし、HTMLCollection や NodeList が渡された場合は ネイティブな JavaScript の振る舞いをするようになっており、classList.add が使えるようになっています。

jQuery を読み込まなくても動くというのも強みですし、逆に jQuery しかわからないチームメンバーがいてもある程度柔軟に使えるのは同じくこのライブラリの強みだと思っています。

スクロールイベントを使っていないので軽い

inview ではユーザの画面内に入ったかどうかをスクロール量で判定しているようです。

つまりこれは、スクロールするたびに毎回スクロール量を取得するイベントが発火しており、ユーザ側にかなり負荷がかかってしまっています。

しかし intersectAction はスクロールイベントを使わずに IntersectionObserver という比較的新しい API を使っているので、実際に交差したときにしかイベントが発火せず、パフォーマンスを損ないません。

ただし、IntersectionObserver は IE などでは使用できません。 IE 対応を求められる案件などでは polyfill (代替)と呼ばれるものを一緒に読み込んであげてください。

以下が W3C という団体が公開している IntersectionObserver の polyfill です。

読み込み例はこんな感じ。

<script src='path/js/intersection-observer.js'></script>
<script src='path/js/intersectAction.js'></script>

コメント

タイトルとURLをコピーしました