お問い合わせはコチラから

Intersection Observerは高速スクロール時に交差検出しないことがある

サイト運営

Intersection ObserverはLazyloadなどでよく使われるJavascriptの組み込み機能す。処理の重いscrollイベントは嫌われ、ScrollイベントをIntersection Observerで置き換えてjavascript記述量や処理軽減するのが最近のトレンドになっています。

サイトのサイドバーにある目次(Table of Contents)ウィジェットで現在の見出しをハイライトする際にIntersection Observerを使えないか?と思ってトライしました。思いもしないトラブルにあったのでメモしておきたいと思います。

Intersection Observerで考査を検出しないことがある

見出し要素をIntersection Observerで交差検出します。その際に、rootmarginを小さく(ビューポートを狭くする)し、かつ、スクロールが高速な場合に、交差検出しない(取りこぼす)トラブルが発生しました。

Intersection Observerのオプションは以下のような設定にしてありました。画面の中央に横線を配置し、それにタッチしたら検出するようなイメージです。

  • rootMargin:-50%,0
  • threshold:0

自分の環境を怪しんで色々試したのですが、原因が全く分からず、半ばあきらめていたのですが、真面目に検索してみると、同様なトラブル事例がありました。

Intersection Observerは、監視対象のDOM要素の位置をチェックする非同期関数をループで実行します。これはブラウザのレンダリングサイクルと組み合わされており、非常に高速に実行されますが(ほとんどのデバイスでは、60 fps、または16.66ミリ秒ごとに1回)、これらのチェックよりも速くスクロールバーを移動すると、IOAPIが一部の可視性の変化を検出しない場合があります。実際、検出されていない要素はレンダリングされていません。

https://stackoverflow.com/questions/61951380/intersection-observer-fails-sometimes-when-i-scroll-fast

スクロールが高速な場合は、Intersection Observerは万能ではないようです。

検出ウィンドウが極小の場合、検出要素が高速で移動していると、検出ウィンドウを通り抜けてから描画されてしまうことが起こり得ます。

色んな条件で試した感じでは、

  • 検出要素に対してビューポートが十分に大きくないと、取りこぼしが発生しやすい

ようです。

私の対策

Intersection Observerのオプションを初期状態からいじらない。

見出し要素はそこそこ小さいので、rootmarginをいじらないか、なるべく狭くしないようにすると取りこぼしが無くなりました。

他の対策:検出要素を大きくする

他のサイトの記事を見ても、見出し要素を検出するのではなく、見出しを含むセクション全体を検出するようにして、検出要素をなるべく大きくしていました。HTML全体を検出要素で綺麗に埋めてしまうイメージになります。HTMLを自動修正してこの方法を適用する場合、見出しの付け方のルールが守られている前提が必要です。ちょっと使いにくい感じがします。

現在の表示位置を目次内に表示する (WebsiteWithPython #3)
the way to make a dynamic index highlight

その他の対策

外部サイトで、解決方法がいくつか紹介されています。

IntersectionObserverの仕様の制限を回避するのではなく、IntersectionObserverを使わない解決方法だったので、私の場合は参考になりませんでした。

Intersection Observer fails sometimes when i scroll fast
I have a little issue with the Intersection Observer API, It works good for me, but. When I scroll fast (very fast) on my webpage, the Intersection Observer API...

上方向のスクロールの検出が難しい

lazyloadのように一度表示したら終わりという処理ならいいのですが、見出しのハイライトではスクロール方向に追従して現在の見出しをハイライトする必要があります。

IntersectionObserverは、見出しがビューポートに入った時に検出されます。rootMarginが0の場合は検出要素が画面に表示されたタイミングで検出となります。

下にスクロールしていくときは問題なくても、上にスクロールしていくときには中々見出しが出てこないので現在表示しているセクションと見出しのハイライトの対応が取れなくなります。

逆方向のスクロールで思った動きにならない理由は、見出しと次の見出しまでの検出要素が無い期間があるためです。この記事の前半で紹介したように、記事全体を検出要素で埋めるようにして、検出要素がない領域を無くせばこのような問題は起きません。しかし、見出しだけを検出要素にしている場合は、逆スクロール時に挙動がおかしくなります。

以下の記事で、その対処方法が書かれていて、その通りにやると逆方向のスクロールで手前の見出しの領域に入ると検出してくれるようになります。

Building a ‘Table Of Contents’ with active indicator using JavaScript Intersection Observers
Prefer a video version? You can watch it on YouTube here. This post covers a modern way of automatically creating a table of contents for your blog post that up...

まとめ

IntersectionObserverは積極的に使っていきたい技術ですが、マウススクロールが高速な場合に描画されない要素は検出できないことがあります。

初期状態のオプションで使用すれば問題は起きませんが、rootmarginを1pxとかの高さにすると交差検出漏れが起きます。

また、見出しハイライトのようなものに適用する場合、逆スクロール時には手前の検出要素がなかなか出てこないのでハイライトがずれたように見えます。

その場合は、特殊な方法で対応する必要がありますので、IntersectionObserverならコーディングが簡単になるというメリットも薄れてしまいます。何でもかんでもIntersectionObserverというのも考え物だと思いました。

この記事が気に入ったら フォローしよう
最新情報をお届けします。
この記事を書いた人
ブーン

はるばる日本よりオランダ王国へやってまいりました。
自分の経験が少しでも参考になれば嬉しいです。
お問い合わせは、『こちら』からお願い致します。

\ブーンをフォロー/
スポンサーリンク
サイト運営
\シェアお願いします!/
\ブーンをフォロー/

失敗しないレンタルサーバーランキング

mixhost

不正アクセスに強くて使いやすいおススメサーバー
\本サイトで利用中/
メリット①:自動ウィルス駆除対応
メリット②:サイトの表示速度が速い!
メリット③:転送量の上限が多い!
メリット④:自由にプラン変更ができ、アクセス増にも対応できる!
メリット⑤:バックアップデータが無料で復元できる!
メリット⑥:Wordpressが簡単にインストールできる!
メリット⑦:どのプランでも初期費用が無料!
メリット⑧:10日間の無料お試し期間と30日の返金保証!

Conoha Wing

国内Wordpress最速の最強サーバー
メリット①:圧倒的な表示速度
メリット②:レンタルサーバーと独自ドメインがセットでお得◎
メリット③:プラン変更はすべてのプランで自由自在
メリット④:一か月の利用転送量の制限が緩い(9TB~)
メリット⑤:WordPresサイトの移行が簡単

エックスサーバー

国内シェアNo1の安定性と実績が魅力。ALL SSDで死角なしの万能サーバー。
メリット①:サイトの表示速度が安定して速い!
メリット②:アクセス負荷に強くて安定性が高い!
メリット③:24時間365日の充実サポートで安心!電話サポートもあり!
メリット④:転送量が多い!
メリット⑤:自動バックアップ機能付き!
メリット⑥:WordPressが簡単にインストールできる!
メリット⑦:10日の無料お試し期間がある!

オランダで生きていく
タイトルとURLをコピーしました