
目次
- iScrollとは
 - なぜposition:fixedを使用しないの?
 - サポートブラウザ
 - 商用利用可能
 - 使い方
 - マウスホイール有効化
 - タップイベント割り当て
 - 水平スクロール
 - clickイベント有効化
 - タップしたとき指定した要素までスクロール
 - 無限スクロール (ajaxで読み込みデータがあるかぎり)
 - 縦、横、斜めにスクロール
 - スクロールバーを表示
 - カスタムしたスクロールバーを表示
 - パララックス スクロール
 - カルーセル(スライダー)
 - キーの上下(↑ ↓)でスクロール
 - 指定した要素をスナップしてスクロール
 - 現在のスクロール位置表示
 - ピンチアウトでのズーム有効化
 - スクロールの有効化・無効化
 - スクロール領域のリフレッシュ
 - 動作しないときの確認項目
 - 備考
 
iScrollとは
スクロールなどを簡単に実装することができるJSライブラリ。
パララックスやカルーセル(スライダー)なども実装可能。
ヘッダーやフッターをposition:fixedで固定してコンテンツ部分をスクロールしたいときの代替としてもよく使用される。
例えばヘッダーとフッターを上下に固定して中央のコンテンツのスクロールを実装する場合はこのようになる。
※デフォルト設定ではスワイプのスクロールのみに対応
なぜposition:fixedを使用しないの?
iScrollはposition:fixedだけでは実現できない機能が簡単に実装可能。また、Android 2.3以下だとposition:fixedが正しく機能しないことがあるため代替としてiScrollが使用されることが多い。
サポートブラウザ
- ほとんどのモダンブラウザに対応
 - iPhoneやAndroidならよほど古くなければ使用できる
 - Internet ExplorerはIE9以上で使用可能
 
商用利用可能
iScrollはMITライセンスのため商用利用可能
使い方
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>
スクロールさせる要素は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: 3000,
		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倍速
 
JavaScript
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
    }]
  });
});
HTML
<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>
CSS
#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);
}
カルーセル(スライダー)
下記のオプションでカルーセル(スライダー)が実装可能。
インジケーターはCSSだけで作成可能。インジゲーターの現在位置の移動距離はindicatorの幅によって変わる。
JavaScript
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
  myScroll = new IScroll('#wrapper', {
    scrollX: true,
    scrollY: false,
    snap: true,
    keyBindings: true,
    indicators: {
      el: document.getElementById('indicator'),
      resize: false
    }
  });
});
HTML
<div id="viewport">
  <div id="wrapper">
    <div id="scroller">
      <div class="slide slide1"><img src="slide1.jpg" width="300" height="200"></div>
      <div class="slide slide2"><img src="slide2.jpg" width="300" height="200"></div>
      <div class="slide slide3"><img src="slide3.jpg" width="300" height="200"></div>
      <div class="slide slide4"><img src="slide4.jpg" width="300" height="200"></div>
    </div>
  </div>
</div>
CSS
#viewport {
  overflow: hidden;
  position: relative;
  width: 300px;
  height: 200px;
  margin: 0 auto;
  background: #444;
}
#wrapper {
  width: 300px;
  height: 200px;
  margin: 0 auto;
}
#scroller {
  position: absolute;
  z-index: 1;
  width: 1200px;
  height: 200px;
  background-color: #444;
}
.slide {
  float: left;
  width: 300px;
  height: 200px;
}
#indicator {
  overflow: hidden;
  position: relative;
  width: 70px;
  height: 10px;
  margin: 10px auto;
}
#indicatorList li {
  list-style: none;
  float: left;
  width: 10px;
  height: 10px;
  border-radius: 10px;
  background: #EEE;
}
#indicatorList li:not(:last-child) {
  margin-right: 10px;
}
#dotty {
  position: absolute;
  z-index: 2;
  width: 10px;
  height: 10px;
  border-radius: 10px;
  background: #777;
}
キーの上下(↑ ↓)でスクロール
keyBindings:trueでキーの上下(↑ ↓)でスクロールが可能になる。スペースキーによるスクロールは不可。
スペースキーでスクロールしたい場合はkeysオブジェクトにspace:32を追加する。
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);
});
ピンチアウトでのズーム有効化
zoom:trueでズーム有効化。デフォルトでは無効化されている。
さらにiscroll.jsではなくiscroll-zoom.jsを読み込まないとズームを有効化できない。
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
  myScroll = new IScroll('#wrapper', {
    zoom: true
  });
});
スクロールの有効化・無効化
// スクロールの有効化 myScroll.enable(); // スクロールの無効化 myScroll.disable();
スクロール領域のリフレッシュ
あとからスクロール領域内にリストが追加されるなどして領域の高さや幅に変更があった場合、refresh()で領域をリフレッシュする必要がある。
var myScroll;
document.addEventListener('DOMContentLoaded', function() {
  myScroll = new IScroll('#wrapper', {
    mouseWheel: true
  });
  $('#a').on('click', function() {
    $('#wrapper > ul').append('<li>add list</li><li>add list</li><li>add list</li>')
  });
  $('#r').on('click', function() {
    myScroll.refresh();
  });
});
動作しないときの確認項目
- iscroll.jsは読み込まれているか
 - iscroll-lite.jsが読み込まれていないか
 - iscroll-infinite.js, iscroll-probe.js, iscroll-zoom.jsでないと動作しないオプションではないか
 - HTML構造や要素名が正しく指定されているか
 - positionプロパティが正しく指定されているか
 - デフォルト設定ではスワイプのスクロールのみに対応
 - myScroll.disable();が有効になっていないか
 - scrollX:falseやscrollY:falseなどでスクロールが無効化されていないか
 - CDN利用の場合はネットに接続できているか
 
備考
- iscroll-lite.jsという軽量化版もあるがほとんどの機能がなくなっているので極力使用しないほうが良い。
 - この記事に記載されているのはiScrollで使用頻度の高いオプション一覧であり、使用頻度の低いものに関しては割愛した。iScrollの詳細を知りたい方は公式サイトをご参照ください。
 
iScroll サンプル一覧
https://iwb.jp/s/iscroll-js-fixed-option-demo/
iScroll サンプル一覧 ダウンロード
iScroll 公式サイト
http://cubiq.org/iscroll-5
iScroll CDN
https://cdnjs.com/libraries/iScroll



