スクロールを実装するiScrollの使い方とオプションとdemo

スクロールを実装するiScrollの使い方とオプションとdemo

iScrollとは

スクロールなどを簡単に実装することができるJSライブラリ。

パララックスやカルーセル(スライダー)なども実装可能。

ヘッダーやフッターをposition:fixedで固定してコンテンツ部分をスクロールしたいときの代替としてもよく使用される。

例えばヘッダーとフッターを上下に固定して中央のコンテンツのスクロールを実装する場合はこのようになる。
※デフォルト設定ではスワイプのスクロールのみに対応

iScroll デフォルト設定

なぜ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;
}

iScroll デフォルト設定

マウスホイール有効化

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 &lt; 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 &amp;&amp; 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 + '&amp;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