OS X Lionぽいスクロールバーを実装できてiOSにも対応した Skroll.js
前略そんなわけでスクロールバー作りました。
一応目指していたところは、PCベースのサイトを作ったときにiOSで見てもスクロールバー実装したとこいい感じになるよ!っていうのです。
PCでLionぽいスクロールバー作りたいなと思って会社の合宿中に始めたのですけど、なんかいつの間にかiOSにも対応することになってて、動きにこだわり始めたら収集つかなくなってめちゃめちゃ時間かかりました・・・
対象バージョンはある程度絞ってあるんですけど、結構納得いく動きにできたかなーと思います。動きはとりあえずPCとiOS(4.2以上)で見てください。
タイトルにないですけど、これはjQueryプラグインとして動作します(jQuery mobileは必要ないです)。自分で使う機会が多ければjQuery外してiOSに特化してもいいかなとかそういうノリなので、もし使う人がいればフィードバックください。
iOS用のスクローラーライブラリでiScrollとかScrollabilityがあるのですが
とりあえずiScrollとかとの違いを
- PCベースで対応(iOSはサブ扱い、半分くらいiOSのコードだけど
- PCとiOSでは動作が違う、それぞれ使いやすいように最適化
サンプル
- PCブラウザとiOSで動作が違います
- refreshメソッドのサンプル – iOS向けによくあるヘッダフッタの固定
二つ目のサンプルはウィンドウの幅を変えてみてください。refresh()メソッドを使うことで、スクロールバーの長さがコンテンツの幅が変わるのに合わせて変わります
ダウンロード
Githubから
使い方
jQueryとskroll.jsを読み込んで実行するだけです。実行する対象はいつもoverflow: auto;にしてる要素です。autoにしておいて、skroll()メソッドを実行すればスクロールバーが置き換わります。このときwidthの指定がある場合は(auto以外の場合)オプションでwidthをしてください。
※ スクロールバーは縦のスクロールバーしか実装できません。
オプション
あまり役に立たないオプションが多いかも・・・
プロパティ | デフォルト |
---|---|
margin | 0 元の要素のmarginがある場合は指定しておく |
width | 置き換えた後のコンテンツ幅、元の幅と同じ |
height | 置き換えた後のコンテンツ高、元の高さと同じ |
inSpeed | 50 スクロールバーが表示される速度 |
outSpeed | 200 スクロールバーが非表示になる速度 |
delayTime | 200 最初に表示されて消えるまでの速度 |
scrollBarWidth | 6 スクロールバーの幅 |
scrollBarSpace | 3 スクロールバーとコンテンツのスペース |
scrollBarColor | “#000″ スクロールバーの色 |
scrollBarZIndex | 100 スクロールバーのzIndex |
opacity | 0.5 スクロールバーの透明度 |
scrollBarBg | false スクロールバーの背景を表示する |
scrollBarBgColor | “#666″ スクロールバー背景の色 |
scrollBarBgOpacity | 0.5 スクロールバー背景の透明度 |
scrollBarGrowth | “0 0 2px #fff” スクロールバーのboxShadow |
cursor.grab | スクロールバーのカーソル:のせたとき、手のアイコン(PC |
cursor.grabbing | スクロールバーのカーソル:掴んだとき、掴んだ手のアイコン(PC |
scrollCancel | 80 スクロールをキャンセルするまでの時間(iOS |
cubicBezier | “”cubic-bezier(0.20,0.71,0.30,0.87)” バウンス以外のeasing(iOS |
cubicBezierBounce | “cubic-bezier(0.11,0.74,0.15,0.80)” バウンス時のeasing(iOS |
cubicBezierBar | “cubic-bazier(0.42,0,1,1)” スクロールバーのeasing |
scrollBarHide | true スクロールバーを自動的に非表示にするかどうか |
メソッド
メソッドを利用する場合は、jQueryオブジェクトに対してskroll()を実行せずに、jQuery.skroll()を実行します。
メソッド名 | 説明 |
---|---|
refresh | スクロールバー領域を再描画する |
var skroll = $.skroll("div.body", { scrollBarBg: true }); // 要素、オプションの順 skroll.refresh(); // 任意のタイミングで
iOSの対応バージョンについて
手元のiOS4.3(iPad2, iPhone4)から見てますが、どちらも普通に使う分には問題ないです。
CPUもしくはGPUが非力なiPhone3Gや3GSではCSS3 Transitionsが綺麗に動作しない可能性があります。TransitionsにはGPUハードウェアアクセラレータを利用しているため、この部分で滲んだりボヤケたりするかもしれません。
というわけで
何かあればGithubからフォークしてください!
Leave a comment
Trackbacks: 1
- Trackback URL for this entry
- Listed below are links to weblogs that reference
- OS X Lionぽいスクロールバーを実装できてiOSにも対応した Skroll.js from 5509
-
pingback from iPhone、iPadでのoverflow:scroll/autoの動作について | SUSH-i LOG [...] https://5509.me/log/skroll [...]
Comments: 12 - Leave a comment
デザインを崩すこと無くスクロールが実現できるので大変重宝させていただいております。
jQuery 1.7.2では動かないようですが、対応予定はありますでしょうか?
.bind(MOUSEWHEEL, function(e) {
e = e || window.event;
if(!e.detail && !e.wheelDelta){e = e.originalEvent;} ←追加
これでPCでも動きました。
(jquery 1.7.2)
同一ページ内に複数設置したいのですが、1つをスクロールすると、もう1つも連動してうごいてしまいます。
どう記述すればよいでしょうか?
スクロールイベントに bind はできないですね。
たしかに出来たほうが便利そうですねー。
ただこれ、ソースコードを書きなおしたいレベルなので
アップデートは当分できないと思います。。
すみません。ちょっとツマズイてしまったので、質問させてください。
$.skrollで要素を指定しますが、指定した要素はスクロール判定はできなくなりますか?
ちょうど「refreshメソッドのサンプル」のdiv class=”body”部分を、
$(“div.body”).scroll(function(){
alert(“a”);
});
とか考えているのですが…よろしくおねがいします。
jquery mobileと併用するとスクロールバーが表示されません。
jquery.mobile.css
と衝突しているのだと思いますが、、。javascriptの衝突問題があの手この手で解消されてきた今、今度はcssのぶつかりが増えてきましたねえ。
そうですねーjQuery mobileは個人的に使わないので未検証でしたね。。
そもそもclass名がストレートすぎたので変えてみます。
github のサンプル index.html をカスタマイズして実際に使うときと同じ状況の検証をしてみたスクリプトの部分です。
var skroll = $.skroll(“div.txt”, {
margin: “2em auto 0″,
width: 300,
scrollBarSpace: 0,
scrollBarBg: true
});
$(‘#btn’).click(function(){
$(‘.txt’).append( $(‘.txt’).html() );
skroll.refresh();
});
これだと scrollOuter の高さが 更新したコンテンツの高さになってしまうようです。 どこかが間違っているのでしょうか?
オプションにheightを指定してみてもだめでしょうか??
他にもカスタムスクロールバーはあるようですが、一番カッコイイと思ったので使わせてもらっています!
実際使ってみて大変簡単に実装もできて助かっているのですが、Ajaxなどでスクロール対象のコンテンツの高さが変わったときにスクロールバーも変わったコンテンツと連動させるにはどうやったらいいのでしょうか?
ソースを読んでみたのですが力不足なため解決できませんでした。。
お手数ですが よろしくお願いします。
さっきちょうど記事を更新したところなのですが、reresh()メソッドを使うとスクロールコンテンツを更新できます。
実行方法が少し変わるのですが
のようにAjax読み込みと描画が終わったあとにrefresh()メソッドを実行してみてください
素早いご返事ありがとうございます。
早速 試してみます!