経緯
なが〜〜いリストをn個ずつ段階的に表示させたかった
クリックすると要素をぬるっと表示する「もっと見る」ボタンは
toggle系メソッドで簡単に出来るのですが、
そのまま使うと表示/非表示の切り替えだけだったのでアレンジ。
※今回は、要素をすべて表示しきったら「もっと見る」ボタンを消すようにしています。
間違っているところがあればご指摘下さい。
参考にさせていただいた記事
大変参考になりました。神です。
デモ
こんな感じです。
HTML/CSS
最初にいくつか表示した状態からスタートします。
HTMLはこちら
細かいところは、伝家の宝刀『割愛』です。
<body>
<div class="container">
<div class="p-tags">
<a class="p-tag">初期表示</a>
<a class="p-tag">初期表示</a>
<a class="p-tag none">ぬるっと後から表示</a>
<a class="p-tag none">ぬるっと後から表示</a>
<a class="p-tag none">ぬるっと後から表示</a>
<a class="p-tag none">ぬるっと後から表示</a>
<a class="p-tag none">ぬるっと後から表示</a>
<a class="p-tag none">ぬるっと後から表示</a>
</div>
<div class="p-more__tags"><a href="#">もっと見る</a></div>
</div>
</body>
CSSはこちら
.p-tags{
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
width: 100%;
margin:10px 0;
}
.p-tag{
display: block;
width: 100%;
background: #333;
color: #fff;
padding: 3px;
margin-bottom: 3px;
}
.p-more__tags{
width: 100%;
background: #ff69b4;
text-align: center;
color: #fff;
padding: 5px 0;
}
.p-more__tags a{
display: block;
color: #fff;
}
.none{
display:none; /* 見せたくない要素は見えないように */
}
jQuery
var num = 2;//何個ずつ表示させていくか指定
$('.p-more__tags').on('click', function() {
const hiddenTags = $('.p-tags a.none');
//noneクラスがついてる要素を指定
var hiddenTagsNum = hiddenTags.length;
//noneクラスがついてる要素の個数を取得
if(num > hiddenTagsNum){
//noneクラスがついてる要素の個数より最初に指定した表示させる数が多かった時
num = hiddenTagsNum;
//表示させる数を残りの要素数に変更
}
hiddenTags.slice(0, num).slideToggle();
//noneクラスがついている要素のうち、最初からnum個目まで表示
hiddenTags.slice(0, num).removeClass('none');
//表示させた要素はnoneクラスを削除
if (num == hiddenTagsNum) {
//表示させるものがなくなったら、ボタンをフェードアウト
$('.p-more__tags').fadeOut();
}
});
解説
順番前後しますが、まずToggle部分から
hiddenTags.slice(0, num).slideToggle();
//noneクラスがついている要素のうち、最初からnum個目まで表示
hiddenTags.slice(0, num).removeClass('none');
//表示させた要素はnoneクラスを削除
イメージで言うと、工場のベルトコンベアですね。
流れてくる非表示状態の要素を前から2個取って、slideToggleで表示。
取った要素はnoneクラスを外してあげて、ベルトコンベアから降ろす。
そうすると、さっきは3、4番目でベルトコンベアから降ろされなかった要素が前に流れてきて事実上1、2個目に。
これを取って・表示して・降ろしてを要素が無くなるまで繰り返します。
if(num > hiddenTagsNum){
//noneクラスがついてる要素の個数より最初に指定した表示させる数が多かった時
num = hiddenTagsNum;
//表示させる数を残りの要素数に変更
}
この処理を挟んでいるのは、上の処理をして最後に残った非表示の要素が
必ずしも2個とは限らないからですね。(割り切れない可能性がある)
もし余りが1の時、numをそのまま2にすると.slice(0, num)
がエラーになってしまいます。
懸念点
display: none;
を最初に見せたくない要素に指定していると、
グーグル先生いわく要素が隠しコンテンツ的な扱いになるとかならないとか。
SEOへの影響を考えると、opacity: 0;
からopacity: 1;
への変化がいいのかなぁ。
知見のある方いらっしゃいましたらコメント下さい。。
まとめ
ざっくりまとめると、
display: none;
が指定されているクラスを付けたり外したりしてるだけです。
それならaddClassやremoveClassでいいじゃないか、
と最初は思ったのですが、
それだと、ぬるっと表示できなかったのと、
cssでアニメーションをつけるにしてもdisplay: none;
と相性が悪い。
そしてめんどくさい(本音)
なのでjQuery頼みでtoggle系メソッドを使いました。