jQuery・タッチデバイスでもそこそこ滑らかなアコーディンパネルを3種類作りました [IE8対応]
「アコーディオンがカクカクすぎるの何とかなりません?」とご要望があったため作成。
様々な場面で使えるよう3種類を用意。
検証済みブラウザとOS
- IE 8~ ※一部CSSはIE8不可
- Firefox
- Google Chrome
- Safari
- Windows 7
- OS X Yosemite
- iOS 8
- Android 4.1
このjQueryで出来ること、出来ないこと
- 出来ること
- PCブラウザで引っ掛かりがない滑らかなアニメーション
- タッチデバイスでも普通のスライドよりずっと滑らか
- 出来ないこと
- アプリ並みの超滑らかスライド
- タッチデバイスでも滑らかな理由
- Julian Shapiro 氏の、 Velocity.js を利用しているため。
要点とコード
- Velocity.js を利用するため、slideToggle ではなく、slideDown / slideUp を使っている
- それ以外は普通のコード
共通コード
1 2 3 | <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script> <script src="//cdn.jsdelivr.net/velocity/1.2.2/velocity.min.js"></script> <script src="js/smoothAccordion.js"></script> |
シンプル ver
- トリガーは dt、コンテンツ部分は dd
- トリガー / 閉じるボタン、どちらでも閉じる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <dl id="accordion"> <dt>後ろで大きな爆発音がした</dt> <dd><img src="//placeimg.com/600/300/animals" alt=""> <p>テキスト</p> <span class="close">× 閉じる</span></dd> <dt>俺は驚いて振り返った</dt> <dd><img src="//placeimg.com/600/300/arch" alt=""> <p>テキスト</p> <span class="close">× 閉じる</span></dd> <dt>Lorem ipsum dolor sit amet</dt> <dd><img src="//placeimg.com/600/300/nature" alt=""> <p>テキスト</p> <span class="close">× 閉じる</span></dd> <!-- /#accordion --></dl> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #accordion { > dt { color: white; @include fs(24); cursor: pointer; position: relative; margin-bottom: 1px; padding: 10px 35px; background: darkgreen; &:hover { background: lighten(darkgreen, 10%); } &:before { @include arrow; width: 12px; height: 12px; top: 50%; left: 10px; margin-top: -7px; } } > dd { margin-bottom: 30px; } .active { background: lighten(darkgreen, 10%); &:before { top: 45%; left: 15px; margin-top: -10px; transform: rotate(135deg); } } .close { width: 100px; color: white; text-align: center; cursor: pointer; display: block; padding: 10px; background: #666; &:hover { background: lighten(#666, 10%); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* Smooth accordion menu Author: KEITA HIRAI URL: keitahirai.net */ $(function() { // var touch = ("ontouchstart" in document) ? "touchstart" : "click"; $("#accordion > dd").hide(); // $("#accordion > dt").on(touch, function() { $("#accordion > dt").on("click", function() { if ($(this).next().css("display") == "none") { $(this).next().velocity("slideDown", {duration: 400}); $(this).addClass("active"); } else { $(this).next().velocity("slideUp", {duration: 400}); $(this).removeClass("active"); } }); // $("#accordion .close").on(touch, function() { $("#accordion .close").on("click", function() { $(this).parent("dd").velocity("slideUp", {duration: 400}); $(this).parent("dd").prev().removeClass("active"); }); }); |
入れ子 ver
- リストタグをツリー状にネストする
- トリガーは .open
- 理論上は、無限にネストしていくことが可能
- ナビゲーションで利用することを想定し、閉じるボタンは無し(設置が面倒くさい)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <ul id="accordion-nest"> <li><span class="open">後ろで大きな爆発音がした</span> <ul> <li><img src="//placeimg.com/600/300/animals" alt=""> <p>テキスト</p></li> </ul> </li> <li><span class="open">親譲りの無鉄砲で小供の時から損ばかりしている</span> <ul> <li><span class="open">俺は驚いて振り返った</span> <ul> <li><img src="//placeimg.com/600/300/arch" alt=""> <p>テキスト/p></li> </ul> </li> </ul> </li> <li><span class="open">Lorem ipsum dolor sit amet</span> <ul> <li><span class="open">この文章はダミーです。</span> <ul> <li><span class="open">文字の大きさ、量、字間、行間等を確認するために入れています。</span> <ul> <li><img src="//placeimg.com/600/300/nature" alt=""> <p>テキスト</p></li> </ul> </li> </ul> </li> </ul> </li> <!-- /#accordion-nest --></ul> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #accordion-nest { .open + ul { margin-bottom: 30px; } .open { color: white; @include fs(24); cursor: pointer; position: relative; display: block; margin-bottom: 1px; padding: 10px 35px; background: darkgreen; &:hover { background: lighten(darkgreen, 10%); } &:before { @include arrow; width: 12px; height: 12px; top: 50%; left: 10px; margin-top: -7px; } } .active { background: lighten(darkgreen, 10%); &:before { top: 45%; left: 15px; margin-top: -10px; transform: rotate(135deg); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* Smooth accordion menu Author: KEITA HIRAI URL: keitahirai.net */ $(function(){ // var touch = ("ontouchstart" in document) ? "touchstart" : "click"; $("#accordion-nest ul").hide(); // $("#accordion-nest .open").on(touch, function() { $("#accordion-nest .open").on("click", function() { if ($(this).next().css("display") == "none") { $(this).next().velocity("slideDown", {duration: 400}); $(this).addClass("active"); } else { $(this).next().velocity("slideUp", {duration: 400}); $(this).removeClass("active"); } }); }); |
横向き ver
- トリガーは dt、コンテンツ部分は dd
- 縦向きと違い、1番目はデフォルトで開いていると想定
- 縦向きと違い、コンテンツ領域が限られるため、開くのは1つのみ
- 新たに増やす場合は、CSSとJSの width を修正する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <dl id="accordion-side"> <dt><span>Heading title</span></dt> <dd><div> <img src="//placeimg.com/200/200/animals" alt=""> <p>テキスト/p> </div></dd> <dt><span>consectetur adipisicing</span></dt> <dd><div> <img src="//placeimg.com/200/200/arch" alt=""> <p>テキスト/p> </div></dd> <dt><span>Lorem ipsum dolor</span></dt> <dd><div> <img src="//placeimg.com/200/200/nature" alt=""> <p>テキスト/p> </div></dd> <dt><span>Heading title</span></dt> <dd><div> <img src="//placeimg.com/200/200/animals" alt=""> <p>テキスト/p> </div></dd> <dt><span>consectetur adipisicing</span></dt> <dd><div> <img src="//placeimg.com/200/200/arch" alt=""> <p>テキスト/p> </div></dd> <dt><span>Lorem ipsum dolor</span></dt> <dd><div> <img src="//placeimg.com/200/200/nature" alt=""> <p>テキスト/p> </div></dd> <!-- /#accordion-side --></dl> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #accordion-side { width: 1000px; height: 250px; > dt { width: 40px; height: 100%; color: white; cursor: pointer; float: left; position: relative; margin-right: 1px; background: darkgreen; span { white-space: nowrap; display: block; padding-left: 35px; transform: rotate(90deg); } &:hover { background: lighten(darkgreen, 10%); } &:before { @include arrow; width: 8px; height: 8px; top: 10px; left: 16px; transform: rotate(135deg); } } > dd { width: 754px; height: 100%; overflow: hidden; float: left; background: lighten(black, 95%); div { padding: 20px; } img { float: left; margin-right: 20px; } } .active { background: lighten(darkgreen, 10%); &:before { top: 10px; left: 13px; transform: rotate(45deg); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /* Smooth accordion menu Author: KEITA HIRAI URL: keitahirai.net */ $(function(){ // var touch = ("ontouchstart" in document) ? "touchstart" : "click"; $("#accordion-side > dd").css("width", "0"); $("#accordion-side > dt:first").addClass("active"); $("#accordion-side > dd:first").css("width", "754px"); // $("#accordion-side > dt").on(touch, function() { $("#accordion-side > dt").on("click", function() { $(this).next().velocity({width: 754}, 500, "ease-out"); $(this).next().siblings("dd").velocity({width: 0}, 500, "ease-out"); $(this).addClass("active"); if ($(this).next().css("width") == "0px") { $(this).siblings().removeClass("active"); }; }); }); |
カスタマイズ
- トリガーの見出し部分を背景画像にしたい
- CSSで background を指定し hover と .active も修正する。
画像は時代遅れかつ面倒なのでやめよう。
- タッチデバイス用に、トリガーの発火を速くしたい
- コメントアウトしているコードを使えばOK。
- 横向き ver をデフォルトで全て閉じた状態にしたい
- 下記コードをコメントアウト。12$("#accordion-side > dt:first").addClass("active");$("#accordion-side > dd:first").css("width", "754px");
問題点
- Android 4.1 でカクつく
- Velocity.js で補正しない状態でも同じなので、これは仕方がない。
- スマホで見ると、大して滑らかではない?
- Velocity.js 無しの slideToggle などと比較すると明らかに滑らか。
Web制作の現場で使うjQueryデザイン入門[改訂新版] (Web Professional Books)
posted with amazlet at 15.08.08
西畑一馬
KADOKAWA/アスキー・メディアワークス
売り上げランキング: 8,924
KADOKAWA/アスキー・メディアワークス
売り上げランキング: 8,924
コメントを投稿する