【実務で使える】JavaScriptでフィルタリング機能を実装する

目次

フィルタリングとは?

フィルタリングとは、ユーザーが特定の条件やキーワードを指定した際に、その分類に当てはまる項目だけを画面上に絞り込んで表示する機能です。

例えばこの後の例でも出てきますが、「Aタイプ」と検索すると、Aタイプのタグがついたアイテムだけを残して他を非表示にしたり、などの機能です。

完成のイメージ

実際に以下でフィルタリング動作を試すことができます。

See the Pen Untitled by わい (@y_programing) on CodePen.

検索窓に、「Aタイプ」「Bタイプ」「Cタイプ」と入力してから検索するボタンを押すと、そのタグがついたリストだけ表示されます。

また、「Aタイプ Bタイプ」で検索すると、AタイプとBタイプのタグ両方があるものだけ取得します。

該当のコード一覧

細かいコードはこちら。

HTML
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>検索機能付きナビゲーション</title>
    <link rel="stylesheet" href="style.css">
    <script src="script.js" defer></script>
</head>

<body>
    <header>
        <h1>タイトル</h1>
        <div class="search-nav-wrapper">
            <div class="search">
                <img class="search-img" src="./search.png" alt="虫眼鏡のアイコン">
                <input id="search-input" type="text">
                <button class="search-btn">検索する</button>
            </div>
            <div class="nav-wrapper">
                <nav>
                    <ul class="mainmenu">
                        <li class="mainmenu-li">
                            <button>メニュー</button>
                            <ul class="submenu">
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                            </ul>
                        </li>
                        <li class="mainmenu-li">
                            <button>メニュー</button>
                            <ul class="submenu">
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                            </ul>
                        </li>
                        <li>
                            <button>メニュー</button>
                        </li>
                        <li class="mainmenu-li">
                            <button>メニュー</button>
                            <ul class="submenu">
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                                <li class="submenu-li"><a href="">サビメニュー</a></li>
                            </ul>
                        </li>
                    </ul>
                </nav>
            </div>
        </div>
    </header>

    <main>
        <div>
            <ul class="item-list">
                <li data-id="a b" data-name="Aタイプ Bタイプ">
                    <div class="item">
                        <div>
                            <span class="a-type">Aタイプ</span>
                            <span class="b-type">Bタイプ</span>
                        </div>

                        <h2>タイトル</h2>
                        <p>説明文が入ります。</p>
                </li>

                <li data-id="a" data-name="Aタイプ">
                    <div class="item">
                        <div>
                            <span class="a-type">Aタイプ</span>
                        </div>
                        <h2>タイトル</h2>
                        <p>説明文が入ります。</p>
                    </div>
                </li>

                <li data-id="b" data-name="Bタイプ">
                    <div class="item">
                        <div>
                            <span class="b-type">Bタイプ</span>
                        </div>

                        <h2>タイトル</h2>
                        <p>説明文が入ります。</p>
                    </div>
                </li>

                <li data-id="a c" data-name="Aタイプ Cタイプ">
                    <div class="item">
                        <div>
                            <span class="a-type">Aタイプ</span>
                            <span class="c-type">Cタイプ</span>
                        </div>

                        <h2>タイトル</h2>
                        <p>説明文が入ります。</p>
                    </div>
                </li>

                <li data-id="a b c" data-name="Aタイプ Bタイプ Cタイプ">
                    <div class="item">
                        <div>
                            <span class="a-type">Aタイプ</span>
                            <span class="b-type">Bタイプ</span>
                            <span class="c-type">Cタイプ</span>
                        </div>

                        <h2>タイトル</h2>
                        <p>説明文が入ります。</p>
                    </div>
                </li>
            </ul>
        </div>
    </main>
</body>

</html>

今回は30記事ある想定ですが、ここまで長くなくてもいいですw

CSS
* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

header {
    display: flex;
    justify-content: space-between;
}

ul {
    list-style: none;
    display: flex;
    gap: 30px;
}

.submenu {
    display: none;
}

.submenu li {
    padding: 5px;
}

.submenu a {
    text-decoration: none;
    color: #fff;
}

li button {
    border: none;
    background: #fff;
}


.mainmenu-li:hover .submenu {
    display: block;
    background: #D93A49;
}

.mainmenu-li:hover .submenu li:hover {
    display: block;
}

.submenu-li {
    /* サブメニューにホバーが当たると、背景色を薄くする */
    background: rgba(217, 58, 73, 0.7);
}

.search-img {
    width: 20px;
    height: 20px;
}

.search {
    display: flex;
    align-items: center;
    gap: 5px;
}

.item-list {
    display: block;
}

.item {
    border-left: 3px solid #333;
    margin: 20px;
    padding: 10px;
}

.a-type {
    color: #fff;
    background: red;
}

.b-type {
    color: #fff;
    background: blue;
}

.c-type {
    color: #fff;
    background: green;
}

.a-type,
.b-type,
.c-type {
    padding: 5px;
}

JavaScript
// フィルタ表示
const searchBtn = document.querySelector(".search-btn");
const searchInput = document.getElementById("search-input");

searchBtn.addEventListener("click", () => {
    const keywords = searchInput.value.trim().split(/\s+/);

    const items = document.querySelectorAll(".item-list li");

    items.forEach(item => {
        const typeName = item.dataset.name;

        const match = keywords.every(keyword =>
            typeName.includes(keyword)
        );

        if (match) {
            item.style.display = "";
        } else {
            item.style.display = "none";
        }
    });
});

さいごに

  • 要素に data-name 属性を付与してフィルタ検索の対象を定義する。
  • split(/\s+/) と every() を組み合わせることで簡単に「AND検索」を実装できる。

ECサイトの商品一覧、ブログ記事検索、FAQページなど、実務のあらゆる場所で応用できる必須パターンです。ぜひご活用ください!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

わい
Web制作未経験から、HTML/CSS(Sass)/JavaScript(jQuery)/WordPressを習得。
営業開始1週間で初案件獲得し、月収40万円を達成。
主にWeb制作に関する話題やコーディング、WordPressなどに役立つ情報を発信しています。

コメント

コメントする

CAPTCHA


目次