モバイルサイトで無限スクロールを取り入れようとしてJavaScriptで実装してみた…のですが、AndroidはいいとしてiOSですんなり動かなくなってしまいました。調査して回避策も見つけたので、それを含めて書き進めていきます。
素直にできなくて
無限スクロール実装というのは、分解すれば3要素から成っています。
- スクロール中にブラウザの高さをチェックする
- 適切な高さに来ていれば次のコンテンツを読み始める
- 読み込んだコンテンツを末尾に追加
ということですが、iOSで素直に実装してみると、ブラウザの末端に当たってから読み込みを開始する、なんていう現象が多発してしまいました。調べてみると、iOSのSafariでは、ブラウザ全体のスクロール中にJavaScriptが止まってしまうらしく、そのままではうまくいかなさそうな感じでした。
ライブラリはあるけれど
他のQiita記事でも紹介されていたiScrollというライブラリがあるとのことだったので、試してみることにしました。このライブラリ、動作原理としては
- すべてのスクロールをJavaScriptで乗っ取って、ブラウザ側には伝えない。
- スクロール量を自前で計算して、自前で表示を動かす
というようなものです。使ってみると…かなり重くて、スクロール感はネイティブのものに対して大きく見劣りするものでした。ブラウザ内アプリのような感じで短いページなら実用できるのかもしれませんが、無限スクロールのような長いページに取り入れると、ページ全体の操作が重すぎて操作感が台無しとなってしまいました。
探し求めれば道が開けた
さらに調べてみると、「ページ全体のスクロールではJavaScriptが止まるけど、ページの一部のスクロールなら問題なく動作する」という情報が得られました。そこで、
- ブラウザ全体に広がるような
<div>
を作る -
overflow-y:auto;-webkit-overflow-scrolling:touch
というようなCSSをかけて、慣性スクロールするようにする - コンテンツ全体をこの
<div>
の中に移動させる - ブラウザ全体がスクロールしないように、CSSやJavaScriptで調整する
-
scroll
イベントはこの<div>
へ割り当てる
というようにすることで、ブラウザネイティブなスクロールを行いつつ、JavaScriptイベントも発生する環境を作ることができました。