iOS 7以下におけるscrollイベントの問題
いわゆる「パララックス」などのスクロール連動型コンテンツを実装する場合、JavaScriptでwindowのスクロール量を連続的に取得し、その結果に応じてリアルタイムに画面描画を変更していく手法が取られます。
// jQuery使用
$(window).on('scroll', function() {
var scrollTop = $(this).scrollTop();
// PCやAndroid、iOS 8以上では画面スクロール操作に応じてスクロール量が連続的に出力される
console.log(scrollTop);
});
ただし、iOS 7以下においては「スクロール中」にscrollイベントが連続的に発生せずに「スクロールが完了したタイミング」で1度だけ発生するため、スクロール操作に完全に連動したシームレスな演出が行えないという問題があります。
iScroll 5を利用した「擬似スクロール」の実装
上記のようなOSの仕様上の問題やブラウザパフォーマンスの観点から、**スマートフォン端末向けのWebページ制作においては「スクロール連動処理を省略する」**という対応がとられる場合が多いかと思います。
しかし、何らかの事情で、「どうしてもiOS 7以下を含めたスマートフォン端末でスクロール連動処理を実装しなくてはならない」という状況に陥った場合には、iScroll というJavaScriptライブラリを利用することで**「それらしい処理」を擬似的に**再現することができます。
以前のバージョンではiScroll本体のJSコードをカスタマイズする必要がありましたが、バージョン5で追加された "iScroll probe edition" で擬似scrollイベントの利用が可能になりました。
実装例
※この例ではjQueryを使用していますが、iScroll自体はjQueryを使用しなくても動作します。
<head>
<script src="jquery.js"></script>
<script src="iscroll-probe.js"></script>
</head>
<body>
<div id="scrollContainer">
<div class="scrollInner">
<!-- スクロールさせたいコンテンツ全体 -->
</div>
</div>
</body>
body {
overflow: hidden;
}
# scrollContainer {
position: absolute;
z-index: 1;
top: 0;
bottom: 0;
left: 0;
width: 100%;
overflow: hidden;
}
// jQuery使用
// iScroll 実行処理
function init() {
var myScroll = new IScroll('#scrollContainer', { probeType: 3, mouseWheel: true, click: true });
// 擬似scrollイベントに関数を紐付け
myScroll.on('scroll', updateScroll);
myScroll.on('scrollEnd', updateScroll);
// デフォルトのtouchイベントを無効化
$(document).on('touchmove', function(e) {
e.preventDefault();
});
}
// 「擬似スクロール量」を更新
function updateScroll() {
var y = this.y >> 0; // this.y で取得できる擬似スクロール量を整数化
moveParallaxObj(y);
}
// 例:パララックス処理
function moveParallaxObj(y) {
var parallaxY = -1 * y / 2;
$parallaxObj.css({top: parallaxY + 'px'});
}
init();
iScrollがやっていることと、利用する上での注意点
iScrollは大まかには以下のような処理を行なっています。
- スクロールさせたい要素を絶対配置し、Webブラウザの本来のスクロール機能を無効にした上で、要素の内容をCSS transformで移動させて擬似的に「画面をスクロールしている」ように見せる。
実際にwindowをスクロールさせているわけではないため、Webブラウザが本来備えている機能(例:ページ内アンカーリンクなど)をそのまま利用することができず、それぞれ独自の実装が必要になります。
思わぬところで作業コストが爆発的に増える可能性があり、導入は慎重に行なったほうが良いでしょう。
iScroll に関する詳細な情報は公式ページかGitHubをご覧ください。