【HTML】簡易的な絞り込み【JavaScript】

どうも、くまだです。

静的ですが、簡易的な絞り込み機能的なものの実装メモ。

簡易的な絞り込み

コードは以下になります。

  <ul class="p-search">
    <li class="p-search__item">
      <button class="c-searchButton is-select" data-category="all">すべて</button>
    </li>
    <li class="p-search__item">
      <button class="c-searchButton" data-category="category1">カテゴリー1</button>
    </li>
    <li class="p-search__item">
      <button class="c-searchButton" data-category="category2">カテゴリー2</button>
    </li>
    <li class="p-search__item">
      <button class="c-searchButton" data-category="category3">カテゴリー3</button>
    </li>
  </ul>

  <ul class="p-cards">
    <li class="p-cards__item p-card" data-category="category2">
      <div class="p-card__img">
        <img src="images/dummy.png" alt="">
      </div>
      <p class="p-card___text">カテゴリー2</p>
    </li>
    <li class="p-cards__item p-card" data-category="category2">
      <div class="p-card__img">
        <img src="images/dummy.png" alt="">
      </div>
      <p class="p-card___text">カテゴリー2</p>
    </li>
    <li class="p-cards__item p-card" data-category="category3">
      <div class="p-card__img">
        <img src="images/dummy.png" alt="">
      </div>
      <p class="p-card___text">カテゴリー3</p>
    </li>
    <li class="p-cards__item p-card" data-category="category1">
      <div class="p-card__img">
        <img src="images/dummy.png" alt="">
      </div>
      <p class="p-card___text">カテゴリー1</p>
    </li>
    <li class="p-cards__item p-card" data-category="category2">
      <div class="p-card__img">
        <img src="images/dummy.png" alt="">
      </div>
      <p class="p-card___text">カテゴリー2</p>
    </li>
    <li class="p-cards__item p-card" data-category="category3">
      <div class="p-card__img">
        <img src="images/dummy.png" alt="">
      </div>
      <p class="p-card___text">カテゴリー3</p>
    </li>
    <li class="p-cards__item p-card" data-category="category1">
      <div class="p-card__img">
        <img src="images/dummy.png" alt="">
      </div>
      <p class="p-card___text">カテゴリー1</p>
    </li>

  </ul>
.p-search {
  display: flex;
  flex-wrap: wrap;

  
  margin-top: 40px;
  max-width: 50%;
  margin-right: auto;
  margin-left: auto;
}

.p-search__item {
  margin-right: 16px;
}

.c-searchButton  {
  background-color: orange;
  padding: 10px;
  border: 2px solid orange;
}

.c-searchButton.is-select {
  background: #fff;
}


.p-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 10px;
  row-gap: 10px;


  margin-top: 80px;
  max-width: 50%;
  margin-right: auto;
  margin-left: auto;

}

.p-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  position: relative;
}

.p-card__img {
  width: 100%;
  display: block;
}

.p-card img {
  width: 100%;
  height: 100%;
  display: block;
}

.p-card___text {
  flex-grow: 1;
}

.p-card__link-wrap {
  margin-top: 10px;
}

.p-card__link {
  padding: 8px;
  display: inline-block;
  background: yellow;
}



document.addEventListener('DOMContentLoaded', function () {
  const buttons = document.querySelectorAll('.c-searchButton');

  buttons.forEach(button => {
    button.addEventListener('click', () => {
      const selectedButton = document.querySelector('.c-searchButton.is-select');
      const category = button.getAttribute('data-category');
      button.classList.add('is-select');

      if (selectedButton !== button) {
        selectedButton.classList.remove('is-select');
      }

      const cards = document.querySelectorAll('.p-cards__item');
      cards.forEach(card => {
        card.style.display = 'none';
      });

      if (category === 'all') {
        cards.forEach(card => {
          card.style.display = 'block';
        });
      } else {
        const categoryCards = document.querySelectorAll(`[data-category="${category}"]`);
        categoryCards.forEach(card => {
          card.style.display = 'block';
        });
      }
    });
  });
});

特定のカテゴリーをクリックしたら、特定のカテゴリーのアイテムのみ表示し、allをクリックしたら、すべてのアイテムを表示する。カテゴリーのボタンは異なるカテゴリーをクリックしたら色が変わり、直前に選択されていたカテゴリーの色も変わる。

ボタンの色の切り替えは、is-selectクラスが付いたら、背景色が白になるようにCSSで調整しています。

カテゴリーのボタンを全て取得して変数に格納します。

const buttons = document.querySelectorAll('.c-searchButton');

各ボタンに対してクリックイベント発火したいのでforEachで回す。forEachの中でクリックイベント設定。

  buttons.forEach(button => {
    button.addEventListener('click', () => {
   // 現在選択中のボタン取得
      const selectedButton = document.querySelector('.c-searchButton.is-select');
      
   // クリックしたボタンにis-select追加
      button.classList.add('is-select');

   // クリックしたボタンでない場合、
      if (selectedButton !== button) {
        // 前に選択していたボタンから 'is-select' クラスを削除
        selectedButton.classList.remove('is-select');
      }

    });
  });

上のコードで、ボタンのis-selectを切り替えできます。

カード全てを取得し、いったん非表示にして初期化。


// すべての "p-cards__item" クラスを持つ要素を非表示にする
const cards = document.querySelectorAll('.p-cards__item');
cards.forEach(card => {
   card.style.display = 'none';
 });

クリックしたボタンのデータ属性を取得します。なお、全てのボタンには、 data-category=”all”、 data-category=”category1″、みたいな感じでデータ属性付与してあります。

 // クリックされたボタンの "data-category" 属性の値を取得
 const category = button.getAttribute('data-category');

if文で変数categoryがallカテゴリーだったら、カードすべて表示。そうでない場合(all以外の特定のカテゴリー)だったら、そのカテゴリーのカードを表示する。

// カテゴリーが 'all' の場合
if (category === 'all') {
   // 'すべて' ボタンがクリックされた場合、すべてのカード要素を表示
    cards.forEach(card => {
      card.style.display = 'block';
    });
} else {
   // 特定のカテゴリーのカード要素を表示
   const categoryCards = document.querySelectorAll(`[data-category="${category}"]`);
   categoryCards.forEach(card => {
      card.style.display = 'block';
   });
}

静的なんで絞り込みっぽい感じのは実装です。

ここまで読んでくださりありがとうございました。

この記事を書いた人