iScrollとは
スクロールなどを簡単に実装することができるJSライブラリ。
例えばヘッダーとフッターを上下に固定して中央のコンテンツのスクロールを実装する場合はこのようになる。
※デフォルト設定ではスワイプのスクロールのみに対応
なぜposition:fixedを使用しないの?
iScrollはposition:fixedでは実現できない機能が簡単に実装可能。また、Android 2.3以下だとposition:fixedが正しく機能しない場合があるため代替としてiScrollが使用されることが多い。
使い方
iscroll.jsを読み込んで適用する要素を下記のように指定する。
<script src="https://cdnjs.cloudflare.com/ajax/libs/iScroll/5.1.3/iscroll.js"></script>
<script>
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper');
});
</script>
CSSはこのように指定。スクロールさせる要素はposition:absoluteで絶対位置。
body, ul, li {
list-style: none;
margin: 0;
padding: 0;
}
#header,
#footer {
position: absolute;
width: 100%;
}
#header a,
#footer a {
display: block;
width: 100%;
height: 30px;
line-height: 30px;
text-decoration: none;
text-align: center;
background: #000;
color: #fff;
}
#header a:hover,
#footer a:hover {
background: #24890d;
}
#header {
top: 0;
}
#header a {
color: #fff;
}
#wrapper {
position: absolute;
z-index: 1;
top: 30px;
bottom: 30px;
left: 0;
width: 100%;
overflow: hidden;
}
#wrapper li {
padding: 10px 0;
text-align: center;
}
#wrapper li + li {
border-top: 1px solid #ccc;
}
#footer {
bottom: 0;
}
#footer a {
color: #fff;
text-decoration: none;
}
マウスホイール有効化
mouseWheel:trueでマウスホイールでのスクロールが可能になる
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
mouseWheel: true
});
});
タップイベント割り当て
tap:trueでタップイベントが使用可能に。iScrollはclickイベントではスマートフォンのタップ時に反応しないため。タップイベント割り当てが必要。
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
tap: true
});
var li = document.querySelectorAll('li');
for(var i = 0; i < li.length; i++) {
li[i].addEventListener('tap', function () {
this.style.background = !this.style.background ? '#f99' : '';
});
}
});
水平スクロール
scrollX:trueで水平スクロールが可能になる。scrollY:falseも忘れずに。
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
scrollX: true,
scrollY: false,
mouseWheel: true
});
});
clickイベント有効化
iScrollはclick:trueがないとclickイベントがスマートフォンで反応しない。
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
click: true
});
});
タップしたとき指定した要素までスクロール
myScroll.scrollToElement(element)でタップした時に指定した要素までスクロールできる。例えば一番最初のliタグにid="first"を付けて下記のように記述すればタップ時にトップに戻ることができる。
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
click: true
});
var first = document.getElementById('first');
var last = document.getElementById('last');
first.addEventListener('click', function() {
myScroll.scrollToElement(last);
})
last.addEventListener('click', function() {
myScroll.scrollToElement(first);
})
});
無限スクロール
(ajaxで読み込みデータがあるかぎり)
- いわゆる無限スクロール
- iscroll-infinite.jsの読み込みが必要
- infiniteElementsで読み込むデータを指定
- infiniteLimitで読み込むデータ数を制限できる
- datasetでajax読み込み
- dataFillerで関数を指定してデータ更新
- cacheSizeでキャッシュサイズ指定
function ajax (url, parms) {
parms = parms || {};
var req = new XMLHttpRequest(),
post = parms.post || null,
callback = parms.callback || null,
timeout = parms.timeout || null;
req.onreadystatechange = function () {
if ( req.readyState != 4 ) return;
if ( req.status != 200 && req.status != 304 ) {
if ( callback ) callback(false);
return;
}
if ( callback ) callback(req.responseText);
};
if ( post ) {
req.open('POST', url, true);
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
} else {
req.open('GET', url, true);
}
req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
req.send(post);
if ( timeout ) {
setTimeout(function () {
req.onreadystatechange = function () {};
req.abort();
if ( callback ) callback(false);
}, timeout);
}
}
var myScroll;
function updateContent(el, data) {
el.innerHTML = data;
}
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
mouseWheel: true,
infiniteElements: '#wrapper > ul > li',
infiniteLimit: 300,
dataset: requestData,
dataFiller: updateContent,
cacheSize: 1000
});
});
function requestData(start, count) {
ajax('dataset.php?start=' + +start + '&count=' + +count, {
callback: function (data) {
data = JSON.parse(data);
myScroll.updateCache(start, data);
}
});
}
縦、横、斜めにスクロール
scrollX:true, freeScroll:trueで縦、横、斜めにスクロールのが可能になる。
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
scrollX: true,
freeScroll: true
});
});
スクロールバーを表示
scrollbars:trueでCSSで描画したオリジナルのスクロールバーを表示。
ほかにもスクロールバーの表示に関するオプションがあるので必要に応じて追加する。
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
mouseWheel: true,
scrollbars: true, /* スクロールバーを表示 */
fadeScrollbars: true, /* スクロールバーをスクロール時にフェードイン・フェードアウト */
interactiveScrollbars: true, /* スクロールバーをドラッグできるようにする */
shrinkScrollbars: 'scale' /* スクロールバーを伸縮 */
});
});
カスタムしたスクロールバーを表示
scrollbars:'custom'で自分で使用したカスタムスクロールバーの使用が可能になる
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
mouseWheel: true,
scrollbars: 'custom'
});
});
CSSは下記のように指定。水平スクロールバーの場合、CSSクラス名は.iScrollHorizontalScrollbar
/* do not fix */
.iScrollVerticalScrollbar {
overflow: hidden;
position: absolute;
z-index: 9999;
}
.iScrollVerticalScrollbar .iScrollIndicator {
width: 100%;
}
/* styled scrollbars */
.iScrollVerticalScrollbar {
width: 16px;
top: 2px;
right: 2px;
bottom: 2px;
}
.iScrollIndicator {
position: absolute;
background: red;
border: 3px solid green;
border-radius: 5px;
box-sizing: border-box;
}
パララックス スクロール
パララックス スクロールが可能になる。ほかのオプションよりもHTML, CSS, JavaScriptの変更箇所が多いので注意。
パララックスには最低3つの画像が必要なので事前に用意する。
indicators:で各オプションを設定
- elは背景画像を表示させる要素を指定
- resize: falseで画像の自動リサイズ無効化。(パララックスには必須)
- ignoreBoundaries: trueでスクロール時の要素の境界を無効化。
(パララックスには必須) - speedRatioYでパララックス画像のスピード調整。0.5だと0.5倍速
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
mouseWheel: true,
keyBindings: true,
indicators: [{
el: document.getElementById('snowfield1'),
resize: false,
ignoreBoundaries: true,
speedRatioY: 0.2
}, {
el: document.getElementById('snowfield2'),
resize: false,
ignoreBoundaries: true,
speedRatioY: 0.4
}]
});
});
<div id="wrapper"> <div id="scroller"></div> </div> <div class="snowfield" id="snowfield2"> <div id="snow2"></div> </div> <div class="snowfield" id="snowfield1"> <div id="snow1"></div> </div>
#wrapper {
position: absolute;
z-index: 3;
width: 100%;
top: 0;
bottom: 0;
left: 0;
overflow: hidden;
}
#scroller {
position: absolute;
z-index: 3;
width: 100%;
height: 4000px;
overflow: hidden;
background: url(snow3.png);
}
.snowfield {
position: absolute;
width: 100%;
top: 0;
left: 0;
bottom: 0;
overflow: hidden;
}
.snowfield > div {
position: absolute;
width: 100%;
overflow: hidden;
}
#snowfield1 {
z-index: 1;
}
#snow1 {
z-index: 1;
height: 2000px;
background: url(snow1.png);
}
#snowfield2 {
z-index: 2;
}
#snow2 {
z-index: 2;
height: 2000px;
background: url(snow2.png);
}
キーの上下(↑ ↓)でスクロール
keyBindings:trueでキーの上下(↑ ↓)でスクロールが可能になる。スペースキーによるスクロールは不可。スマートフォン専用サイトには不要な設定。
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
keyBindings: true
});
});
指定した要素をスナップしてスクロール
snap:'li'のようにスナップさせる要素を指定。グリッドデザインだとピタッと吸着して途中で切れずに表示できるようになる。
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
myScroll = new IScroll('#wrapper', {
snap: 'li'
});
});
現在のスクロール位置表示
- スクロール位置の取得にはiscroll-probe.jsの読み込みが必要
- probeType: 3でスクロール位置の取得が可能
- probeTypeは位置取得の精度のオプションで1から3まである。数字が大きいほどCPUの負担も大きくなるが通常であれば3でも問題ない
- 'scroll'でスクロール中の位置を取得
- 'scrollEnd'でスクロール終了後の位置を取得
- this.y >> 0 はビットシフト演算子による小数点切り下げ
var myScroll;
var position;
function updatePosition () {
position.innerHTML = this.y >> 0;
}
document.addEventListener('DOMContentLoaded', function() {
position = document.getElementById('position');
myScroll = new IScroll('#wrapper', {
probeType: 3,
mouseWheel: true
});
myScroll.on('scroll', updatePosition);
myScroll.on('scrollEnd', updatePosition);
});
備考
- iscroll-lite.jsという軽量化版もあるがほとんどの機能がなくなっているので極力使用しないほうが良い。
- この記事に記載されているのはiScrollで使用頻度の高いオプション一覧であり、使用頻度の低いものに関しては割愛した。iScrollの詳細を知りたい方は公式サイトをご参照ください。
iScroll サンプル一覧
http://iwb.jp/s/iscroll-js-fixed-option-demo/
iScroll 公式サイト
iScroll CDN
https://cdnjs.com/libraries/iScroll
