見出し画像

【jQuery】タブ切り替え「お知らせリスト」作成

jQueryを使って、Webページにタブ切り替え機能を実装する方法です。
(後日、ページネーションもjQueryで実装予定。)

カテゴリ毎にコンテナを分けると、リストを追加する際にスクロールして目的の挿入位置を探すのが少し面倒なので、リスト最上部に追加してカテゴリを指定しておけば、勝手にタブ分けできるようにしてあります。

ちなみにお知らせのサンプルテキストはChatGPTに作ってもらいました!


まず最初に、完成品

作業の流れ

  1. HTMLとCSSで静的にコーディング

  2. jQueryでタブ切替実装

では解説を

1. HTMLとCSSで静的にコーディング

HTML構造としては、
「切替タブ<ul id="js-tabs" class="b-tabs">」

「お知らせリスト<div id="js-articles" class="b-articles">」
の2つだけ!

【解説】切替タブ

〇 HTML

<ul id="js-tabs" class="b-tabs">
    <li id="all" class="cat-all active"><button>全て</button></li>
    <li id="design" class="cat-design"><button>Webデザイン</button></li>
    <li id="programing" class="cat-programing"><button>プログラミング</button></li>
    <li id="books" class="cat-books"><button>書籍紹介</button></li>
    <li id="other" class="cat-other"><button>その他</button></li>
</ul>

基本的にIDはjsで使用するための設定です。
classはカテゴリ毎に色分けするのに使用。
class名にactiveとなっているのが、現在表示されているタブです。

〇 CSS(CodePen 37~70行)

/* tab ----------------*/
.b-tabs {
  display: flex;
  justify-content: space-between;
  background: #fff;
  padding-bottom: 2px;
  filter: drop-shadow( 0 4px 2px rgb( 0 0 0  / .1 ));
}
.b-tabs li {
  display: block;
  width: calc( 98% / 5 );
}
.b-tabs button {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 40px;
  padding: .5em 1em;
  opacity: .7;
  font-size: .8em;
  text-align: center;
  border-radius:  5px 5px 0 0;
}
.b-tabs .active button,
.b-tabs button:hover {
  transform: translateY(2px);
  opacity: 1;
}
.b-tabs .active button {
  font-weight: 700;
  pointer-events: none;
  color: #fff;
}

【解説】お知らせリスト

〇 HTML

<div id="js-articles" class="b-articles">

    <article class="b-post">
        <a href="#">
            <div class="b-postDate">
                <span class="e-catName" data-cat="other">その他</span>
                <time class="e-time" datetime="2024-10-07">2024.10.07</time>
            </div>
            <h1 class="e-postTitle">オンラインポートフォリオの作り方</h1>
        </a>
    </article>

    <article class="b-post">
        <a href="#">
            <div class="b-postDate">
                <span class="e-catName" data-cat="programing">プログラミング</span>
                <time class="e-time" datetime="2024-10-06">2024.10.06</time>
            </div>
            <h1 class="e-postTitle">JavaScriptの基本文法を学ぶ</h1>
        </a>
    </article>

    <article class="b-post">
        <a href="#">
            <div class="b-postDate">
                <span class="e-catName" data-cat="design">Webデザイン</span>
                <time class="e-time" datetime="2024-10-05">2024.10.05</time>
            </div>
            <h1 class="e-postTitle">Webフォントの選び方と適用方法</h1>
        </a>
    </article>

    <!-- //////////// 省略 //////////// -->  

    <article class="b-post">
        <a href="#">
            <div class="b-postDate">
                <span class="e-catName" data-cat="other">その他</span>
                <time class="e-time" datetime="2024-08-17">2024.08.17</time>
            </div>
            <h1 class="e-postTitle">エンジニアとしての自己ブランディング戦略</h1>
        </a>
    </article>

</div>

お知らせ記事はarticleで囲まれた部分。
ポイントはdata属性でカテゴリ設定をしていること。
data-catで設定した値は、切替タブのそれぞれのタブに設定されたIDと同じとなっていて、タブとdataの値が一致したら表示させる、という仕組みになっています。
(article自体にdeta設定して、「Webデザイン」といった表記もjQueryで表示させた方がHTMLがシンプルで間違いないかも・・・)

〇 CSS (CodePen 72~123行)

/* post ----------------*/
.b-post {
  position: relative;
  overflow: hidden;
}
.b-post::before{
  content: "";
  display: block;
  width: 120%;
  height: 100%;
  position: absolute;
  right: 120%;
  transform-origin: left;
  transform: skewX(25deg);
  background-image: linear-gradient(150deg, #fff 0%, #fff 25%, #fef9d7 100%);
  z-index: -1;
  transition: .4s ease-out;
}
.b-post:hover::before {
  right: -10%;
}
.b-post a {
  display: flex;
  flex-wrap: wrap;
  padding: 30px 0 30px .8em;
  border-bottom: 1px dashed #ccc;
}
.b-postDate,
.e-postTitle {
  margin: .3em 0;
}
.b-postDate {
  display: flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
  align-items: center;
}
.e-time {
  font-size: .9em;
}
.e-catName {
  display: inline-flex;
  align-items: center;
  margin: 0 1em;
  padding: .2em .5em;
  border-radius: 3px;
  font-size: .75em;
  color: #fff;
}
.e-postTitle {
  line-height: 1.5;
}

2. jQueryでタブ切替実装

// 変数定義

var $tab = $('#js-tabs li'),
$post = $('#js-articles .b-post');

// ready(ページ読み込み時の動作)

$post.addClass('show');

// タブ切替
$('#js-tabs button').off('click').on('click', function() {
var tabData = $(this).parent('li'),
    category = tabData.attr('id');

$tab.removeClass('active'); // -- すべてのタブからactiveクラスを削除
tabData.addClass('active'); // -- クリックされたタブにactiveクラスを追加

// カテゴリ抽出
$post.hide();
if (category === 'all') {
    // -- 「全て」ボタンをクリックした場合は全て表示
    $post.show().addClass('show');
} else {
    // -- 関数「カテゴリー分類」を実行
    categoryClassification(category);
}
});

/*----------------------------------------------
関数
----------------------------------------------**/

// カテゴリー分類
function categoryClassification(category) {
$post.removeClass('show');
$post.each(function() {
    var postCategory = $(this).find('.e-catName').data('cat');
    if (postCategory === category) {
        $(this).show().addClass('show');
    }
});
}

上記にもありますが、お知らせ(article)のdata-catで設定した値は、切替タブのそれぞれのタブに設定されたIDと同じとなっていて、タブとdataの値が一致したら表示させる、という仕組みになっています。

【ざっくり解説】

※ところどころに出てくるクラスshowは、後日公開予定のページネーション実装の仕込みなので、一旦スルーでOK!

  1. タブ(button)をクリックしたら、
    変数tabにその親タグのli、(14行目)
    変数categoryにliのID、(15行目)
    を格納。

  2. 全てのタブ(li)からクラスactiveを一旦削除して、クリックしたタブ(li)にクラスactiveを付ける(17、18行目)

  3. 一旦全てのお知らせを非表示(21行目)

  4. 1で取得した変数categoryが "all"だった場合には、お知らせを全て表示(24行目)

  5. 変数categoryが "all"以外の場合は、categoryに格納されている値を使って、関数categoryClassificationを実行

【関数の解説】

(36~44行)

function categoryClassification(category) {
    $post.removeClass('show');
    $post.each(function() {
        var postCategory = $(this).find('.e-catName').data('cat');
        if (postCategory === category) {
            $(this).show().addClass('show');
        }
    });
}
  1. お知らせ(article)全てに処理するよ(38行目)

  2. 変数postCategoryにカテゴリが表記されているspan.e-cateNameのdata-catを格納(39行目)

  3. 変数postCategoryの値が、変数categoryと一致したら表示(40~42行)


以上です!


いいなと思ったら応援しよう!