position:fixedを実現するiScrollを使う際に覚えておきたいメソッドたち

ヘッダーやフッター等の要素を固定表示するのに利用されるposition:fixed。このposition:fixedがサポートされていない環境で、固定表示を実現する際によく使われるライブラリにiScrollがあります。要素を固定するというよりは、特定要素の範囲をスクロール可能にする、overflow:autoのようなイメージです。

複雑なレイアウトになると、iScrollでスクロールさせている要素の高さが動的に変化したり、スクロール領域が入れ子だったり・・・ユーザ操作に応じて追加の処理を行う必要があります。難しそうなレイアウトは設計の際に回避したいところですが、そういう実装が必要な場合に使えるiScrollのメソッドをまとめてみました。

iScrollの使い方

iScrollの使い方ですが、HTML要素に任意のIDを付け、JSで初期化を行います。下記の例ではid=”scroller”の要素がスクロール可能になります。例でリスト要素になっている部分は何でもかまいませんが、2つのwrapper(例ではIDがwrapperとscrollerのdiv要素)は必要です。また、一番外側の要素には高さを指定しておく必要があります。

◆HTML

<div id=”wrapper”>
<div id=”scroller”>
<ul>
<li></li>


</ul>
</div>
</div>

◆JS

$(function(){
var myScroll = new iScroll(‘wrapper’);
});

◆CSS

#wrapper { height:300px; }

スクロール対象のエリアのサイズが変更された場合

iScrollでは、スクロールエリアのサイズが変更になった場合でも、スクロール可能な範囲は初期化時のサイズのまま変化しません。スクロール可能な範囲を変更したい場合はrefreshメソッドを呼ぶ必要があります。

// iScroll領域のリサイズ
myScroll.refresh();

iScrollを一時的に無効にしたい

disableメソッドを呼ぶと、iScrollのスクロールを一時的に無効にすることができます。スクロール中の場合でもスクロール位置はそのままで解除されます。逆に、スクロールを復活させたい場合はenableメソッドを使います。

// iScrollを無効にする
function disableScroll(){
myScroll.disable();
}
// iScrollを有効にする
function enableScroll(){
myScroll.enable();
}

iScrollを入れ子にしたい

少し無理矢理かもしれませんが、iScrollを入れ子にしてみました。入れ子の場合、外側用と内側用の2つのiScrollインスタンスを用意します。何もせずただ2つのエリアを初期化してしまうと、2つのスクロールが干渉しておかしな動きになってしまうので、iScrollのオプションであるonScrollEndやonTouchEnd、onBeforeScrollStart、onBeforeScrollMoveを使います。
このオプションへスクロールの実行前後に実行する関数を登録できるので、スクロールが始まった際に、スクロールしようとする対象が内側の要素だった場合は外側のスクロールを無効にし、内側の要素のスクロールが完了した時点で外側のスクロールを再度有効にします。

// 外側のiScrollの初期化
myScrollOuter = new iScroll(“outerWrapperId”, {
useTransform: false,
onBeforeScrollStart: function (e) {
// イベントの発生元をチェックして、
内側の領域がスクロールされようとしている場合は外側のiScrollを無効にする
if(!isOwn(e.target)){
myScrollOuter.disable();
}
},
onBeforeScrollMove: function(e){
if(!isOwn(e.target)){
myScrollOuter.disable();
}
}
});

// 内側のiScrollの初期化
myScrollInner = new iScroll(“innerWrapperId”,{
// 外側のiScrollを有効にする
onScrollEnd: function(e){
myScrollOuter.enable();
},
onTouchEnd: function(e){
myScrollOuter.enable();
}
});

iScrollインスタンスを破棄する

ページ内遷移等で再度iScrollを初期化する必要がある場合には、iScrollインスタンスを破棄して新しく作り直します。破棄にはdestroyメソッドを用います。ライブラリ内部ではスクロールバーやイベントリスナーの削除が行われます。

if(myScroll !== null){
myScroll.destroy();
}
myScroll = null;

iScrollを使う際に注意すること

iScrollは、スクロール制御のため、tap周りの動作を取得しています。なので、スクロール対象のエリアにinputエリアやselect、textarea等が含まれる場合、iScrollにイベントを取られてしまい、動作しない場合があります。その場合はonBeforeScrollStart内でイベントの発生元のtagNameを判別する必要があります。

onBeforeScrollStart: function (e) {
var tagName = e.target.tagName;
if (tagName != ‘SELECT’ && tagName != ‘INPUT’ && tagName != ‘TEXTAREA’){
e.preventDefault();
}
・・・
}

まとめ

今回はiScrollを利用する上で使えそうなメソッドをいくつか紹介させていただきました。iScrollの本体は、1000行ちょっとと多くはありません。ソースコードを覗いてみることで、イベントの種類やスクロールバー表示の有無などどんなデフォルトオプションがあるか、使えるパブリックメソッドがどれかなどをざっと把握することができるので、使えそうなメソッドが無いか覗いてみるのもいいかもしれません。

Related Post

ドットDNP「ウェブから学ぶ電子出版の可能性~多様な読書スタイルを考える~」参加レポートドットDNP「ウェブから学ぶ電子出版の可能性~多様な読書スタイルを考える~」参加レポート

5月7日、弊社のドットDNPにてゴールデンウィークのスペシャルイベント「ウェブから学ぶ電子出版の可能性~多様な読書スタイルを考える~」が開催されました。 株式会社ミツエーリンクスの木達一仁さんと、株式会社Gaji-Laboの山岸ひとみさんをお招きし、Webデザインにおけるアクセシビリティの取り組みと、サービスとしての読書体験についてそれぞれ講演いただきました。本記事では、その内容を抜粋してご紹介致します。 Webデザインにおけるアクセシビリティへの取組み 読書体験を考える ――サービスとしての読書体験 トークセッション セミナーを終えて Webデザインにおけるアクセシビリティへの取組み

Canvasに画像を複数枚重ねて描画するにはCanvasに画像を複数枚重ねて描画するには

HTML5のCanvasには画像を組み込むことができます。Canvas上に複数枚の画像(透過PNG)をレイヤー状に順番に重ねたり、重ねた後の画像を取得する方法を解説します。 画像のプリロード  画像を複数枚重ねる場合、単に描画のループを回してしまうと読み込みが完了されたものから表示れ、重ねる順番が保障されない為、描画の前に順にImageオブジェクトを先読みしておきます。 var fileArry = [‘imgName1’,’imgName2’…]; // 読み込みたい画像のパスの配列 var

SVGアニメーションの再生タイミングについてSVGアニメーションの再生タイミングについて

今回は前回書きました『IllustratorからSVGを書き出して、SVGアニメーションを追加する』の関連記事です。SVGアニメーションの再生タイミングにかなりハマったのでもう少し詳しくご紹介したいと思います。OPERAさんの2006年(!)の記事に、詳しい解説がありましたので、参考にしています。こうして見てみると、枯れた技術かと思われていたSVGに再び光が当たった感がありますね。  animate要素の追加  例えば、以下のようなanimate要素を追加したい場合。 <animate attributeName=”opacity” begin=”indefinite” to=”0″ dur=”0.25″ fill=”freeze”