私はなぜか「もっと見る」ボタンを実装することがやたらと多いので、いろいろなやり方を試す中で「これが一番シンプル!」と発見した方法を書いておきます。
要件
- 一覧があり、最初は6件表示されている
- 「もっと見る」ボタンをクリックすると6件ずつ表示される
- もっと見るものがなくなったら、「もっと見る」ボタンは消える
- データのロードは最初に全件行う。「もっと見る」をクリックしたときにロードするわけではない
- したがって、速度を速くする目的ではなく、一覧の量が多いので隠しておきたい時に使えるものを実装する
デモ
デモを作成しましたので以下のリンクから動作確認ができます。
もっと見るボタン - codepen
この「もっと見る」ボタンのおすすめポイント
- jsがたったの8行!
- htmlはn件ごとにdivで区切ったりする必要なし
- 「もっと見る」をクリックして出現する時、ささやかなアニメーションつき
実装のポイント
詳しい実装はデモのcodepenを見てほしいのですが、jQueryでやっていることは下記のような内容です。
- 最初の6件以外を非表示にする
- 「もっと見る」をクリックしたら、非表示になっている項目の頭から6件だけ表示する
- 表示後、非表示の項目が0件の場合は、「もっと見る」ボタンを非表示にする
実装は以下のようになっています。
var moreNum = 6;
$('.list li:nth-child(n + ' + (moreNum + 1) + ')').addClass('is-hidden');
$('.more').on('click', function() {
$('.list li.is-hidden').slice(0, moreNum).removeClass('is-hidden');
if ($('.list li.is-hidden').length == 0) {
$('.more').fadeOut();
}
});
1. 最初の6件以外を非表示にする
「最初の6件以外」をどう取得するかがポイントですが、cssのnth-child
という疑似クラスを使用しました。以下のコードの部分です。
$('.list li:nth-child(n + ' + (moreNum + 1) + ')').addClass('is-hidden');
.list li:nth-child(n + 7)
とすることで、**「listクラス内のliタグの7番目以降」**が取得できます。nth-child
は大変便利で、jsでロジックを書かなくてもcssのセレクタだけでn番目、n以前、n以降、最初、最後などが取得できます。
2. 「もっと見る」をクリックしたら、非表示になっている項目の頭から6件だけ表示する
こちらは以下のような実装をしました。
$('.list li.is-hidden').slice(0, moreNum).removeClass('is-hidden');
非表示の要素にはis-hidden
クラスが付与されるので、これをセレクタにします。
6件目までを取得するには配列のslice
メソッドを使用しています。slice
は、配列の0から6までの要素をコピーして新しい配列を返すメソッドです。
最初はnth-child
でできないか試してみたのですが、この場合では難しかったです。
li.is-hidden:nth-child(-n + 6)
とか
li.is-hidden:nth-of-type(-n + 6)
とか
これらはうまくいきません。理由はnth-child
もnth-of-type
もタグに対して何番目かを選択できるもので、is-hiddenなどのクラス要素内で何番目かは選択できないのでした。
スライドアニメーションの実装方法
アニメーションはcssで実装しています。以下はアニメーション部分のcssの抜粋です。
.list li {
opacity: 1;
height: 32px;
margin-top: 10px;
transition: all 0.4s ease 0s;
}
.list li.is-hidden {
opacity: 0;
height: 0;
margin: 0;
}
.list li {...}
に書かれているのが表示状態のスタイルで、
.list li.is-hidden {...}
に書かれているのが非表示状態です。
非表示→表示に変わる時の変化の指定をしているのが、transition
プロパティです。transition
はアニメーション関連の設定のショートハンドです。一言で解説すると「0.4秒で変化しろ!」という指定となっています!
「非表示のスタイルはdisplay:none;
でいいんじゃないの?」と思う方もいるかもしれませんが、ダメなのです。
transition
できるプロパティとできないプロパティがあるためです。そのため、非表示→表示や表示→非表示にアニメーションを入れたい場合、opacity(透明度)をよく使っています。fadeIn・fadeOutの効果が出せておすすめです。
今回はheight
にも変化をつけたため、「fadeInしながらスライド」みたいなアニメーションになりました。
この実装の問題点
初回表示時に全件表示されたあと7件目以降が隠れるところのが一瞬見えてしまいます。もっと良い実装をするなら、アニメーション時だけ特定のクラスを付与すると良いのですが…それはまたの機会に…。
気になる場合はアニメーションをやめると良いと思います。
まとめ
css疑似クラスのnth-child
やjs配列のslice
メソッドを使って、n番目以降やn番目以前を取得する方法をご紹介しました。こういうテクを知っていればごりごりロジックを書く必要がなくなって便利ですね!
参考記事
何番目系の便利なCSSまとめ
【CSS】nth-childとnth-of-typeでもう混乱しない。
【CSS3】Transition(変化)関連のまとめ