作成する機会がありました。
フリックで行を動かしたりページを変えてみたりしたのですが、
なんとこれでページのスクロールができなくなってしまいました!
原因は、touchstart、touchmove、touchendに紐づけていた
関数で利用したpreventDefault()。
touchイベントでpreventDefault()を使うと、
デフォルトのスクロールが効かなくなってしまうんですね!(@▽@)
これを回避するために、今回iScrollというものを使ってみました。
え?そもそもpreventDefault()使うのが間違っている?
おっしゃるとおりなんですが、画面の上をスワイプしたりページをAJAX通信で
変更させてみたりするときにpreventDefault()を使わざるをえなかったんですorz
----------
では、iScrollの基本的な使い方を解説していきます。
■この記事の対象者■
下記を満たす方
- jQuery を触ってみたことがある
- html を書いてみたことがある
- cssでの「#hoge」や「.hoge」といった
書き方が何を意味しているか分かる
■作成するページ■
ページの一部をスクロールできるページ
まずはiScroll 4から iscroll-4.zip をダウンロードします。
ダウンロードしたzipを解凍して、iscroll.jsがあるのを確認します。
iscroll.jsを入手できたら、htmlとcssを準備します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title></title>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="application/javascript" src="./src/iscroll.js"></script>
<style type="text/css" media="all">
/* iscrollとは関係ないスタイル */
div {
margin: 0;
padding: 0;
}
#wrapper {
padding: 10px;
background-color: #ffaaff;
}
#wrapper-scroll {
height: 100px;
background-color: #ffffff;
}
#layer01 {
height: 150px;
background-color: #aaffff;
}
#layer02 {
height: 150px;
background-color: #ffffaa;
}
</style>
</head>
<body>
<div id="wrapper">
<div id="wrapper-scroll"> <!-- wrapper -->
<div id="layer01"> <!-- scroller -->
<script type="text/javascript">
for(var i = 1; i <= 9; i++) {
document.write(i + "行目<br />");
}
</script>
</div>
<div id="layer02">
<script type="text/javascript">
for(var i = 1; i <= 9; i++) {
document.write(i + "行目<br />");
}
</script>
</div>
</div>
</div>
</body>
</html>
見た目はこうなります。

1つ1つ説明していきますネ。
■プラグインへのリンク
<head>内で jQuery と flickSimple にリンクを張ります。
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="application/javascript" src="./src/iscroll.js"></script>
iScroll は jQuery を使用しているので、
iScroll の前に jQuery にリンクを張ってあげてください。
iScroll のスクリプトのパスは、どこに iScroll をダウンロードしたかで変わります。
■html
<div id="wrapper">
<div id="wrapper-scroll"> <!-- wrapper -->
<div id="layer01"> <!-- scroller -->
<script type="text/javascript">
for(var i = 1; i <= 9; i++) {
document.write(i + "行目<br />");
}
</script>
</div>
<div id="layer02">
<script type="text/javascript">
for(var i = 1; i <= 9; i++) {
document.write(i + "行目<br />");
}
</script>
</div>
</div>
</div>
id が「wrapper-scroll」の中身をスクロールできるように組んでいます。
iScroll適用後にスクロールしているのが分かりやすいよう、
wrapper-scroll の中身が wrapper-scroll より大きくなるように
CSSで設定しています。
Google Chrome の Developer tools で確認すると、wrapper-scroll の位置が分かりますネ。
スクロール時に見えている高さを決める wrapper-scroll 部分は
ページ全体で一意に決まる要素になっている必要があります。
なので、id名をふってあげましょう。
■iScroll を適用する。
細かい説明は後回しにして、iScroll を適用します。
<head>内に下記を追加してください。
<script type="text/javascript">
$(window).load(function(e) {
new iScroll("wrapper-scroll");
});
</script>
new iScroll()の引数にはフリックさせる範囲を示す要素の id 名を指定します。
iScroll を適用すると、見た目がこのように変わります。

一番下までスクロールするとこんな感じ。

iScroll 適用前と見た目がだいぶ変わりましたね。
id が layer02 の要素は見えもしません。
オマケに生成された html を Developer tools で確認すると、
なんだかごちゃごちゃしているのが分かります。

ここで、iScroll の仕組みを説明しましょう。
iScroll は new iScroll() の引数で指定した要素をスクロールの表示画面に、
その要素の1番目の子供を実際にスクロールして見たい html とみなします。
なので、new iScroll() の引数に指定した id="wrapper-scroll" の要素の
範囲のみが見えるようになりました。
そして、1番目の子供の id="layer01" の要素をスクロールして見れるようになっています。
2番目の子供は無視されてしまうので、下までスクロールしても見えません。
でも、消されたわけではないので、ちゃんといます。

iScroll は実際にスクロールしたい要素を動かしてスクロールしているように見せかけています。
なので、id="layer01" に指定された style の値はスクロールする度に変化します。
また、iScroll は独自のスクロールバーを出すので
id="wrapper-scroll" の最後にスクロールバー用の<div>が追加されています。
スマフォではスクロール時だけスクロールバーが見えるようになります。
----------
この状態では画面の一部分しかスクロールできませんが、
wrapper-scroll と 1番目の子供を画面全体を囲む div にしてあげれば、
画面全体をスクロールすることができます。
■iScroll 注意点
iScroll を適用すると、長押し(ロングタップ)でコピー・ペーストダイアログが表示されなくなります。
これは、touchstart を受け取った場合に preventDefault() を実行しているためです。
長押し(ロングタップ)を無効化したくない場合は、
iscroll の iScroll = function・・・ 内を下記のように改造します。
onRefresh : null,
onBeforeScrollStart : function(e) {
// e.preventDefault(); // comment out : 長押し有効化のため
},
onScrollStart : null,
// onBeforeScrollMove: null, // comment out
onBeforeScrollMove : function(e) { // add : デフォルトスクロール無効化のため
e.preventDefault();
},
----------
では、今回はここまで!