You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现点击分类显示子分类,点击子分类后通过JS筛选产品?

实现层级分类切换与产品筛选功能(修复代码错误)

原代码存在的核心问题

  • 未建立父分类(Running/Flying)与子分类(Cat/Dog/Bird)的关联逻辑,无法触发子分类的显示/隐藏
  • 父分类点击后无对应产品匹配逻辑,导致功能失效
  • 缺少子分类容器的默认隐藏与切换控制代码

修改后的完整实现代码

HTML(调整分类关联与初始状态)

<header class="header">
    <div class="filter-category">
        <button class="button button_type_all" data-filter="all">All</button>
        <button class="button button_type_running" data-parent="running">Running</button>
        <button class="button button_type_flying" data-parent="flying">Flying</button>
    </div>
    <!-- 子分类容器默认隐藏,添加父分类标识 -->
    <div class="filter filter-hidden" data-parent-target="running">
        <button class="button button_type_cat" data-filter="cat">Cat</button>
        <button class="button button_type_dog" data-filter="dog">Dog</button>
    </div>
    <div class="filter filter-hidden" data-parent-target="flying">
        <button class="button button_type_bird" data-filter="bird">Bird</button>
    </div>
</header>
<main class="content">
    <div class="container">
        <div class="card cat running">Cat</div>
        <div class="card dog running">Dog</div>
        <div class="card bird flying">Bird</div>
        <div class="card dog running">Dog</div>
        <div class="card cat running">Cat</div>
        <div class="card bird flying">Bird</div>
        <div class="card bird flying">Bird</div>
        <div class="card dog running">Dog</div>
        <div class="card cat running">Cat</div>
    </div>
</main>

CSS(添加隐藏类与样式优化)

:root {
  --color-orange: #ffa728;
  --color-red: #e66c6e;
  --color-green: #a7d6bb;
  --color-blue: #1c4961;
  --color-sky: #58C9E2FF;
  --color-brown: #a56e47;
}

*,
*::after,
*::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Courier New", Courier, monospace;
  font-size: 16px;
  line-height: 1.2;
  background-color: #faebd7;
}

.header {
  padding: 20px 0;
  margin-bottom: 48px;
}

.filter {
  display: flex;
  justify-content: center;
  max-width: 1024px;
  margin: 0 auto;
  margin-top: 12px;
}

.filter-category {
  display: flex;
  justify-content: center;
  max-width: 1024px;
  margin: 0 auto;
  padding-bottom: 20px;
}

/* 添加子分类隐藏类 */
.filter-hidden {
  display: none;
}

.button {
  padding: 12px 24px;
  margin-right: 18px;
  cursor: pointer;
  color: white;
  text-transform: uppercase;
  font-weight: bold;
  border: 0;
  outline: none;
  border-radius: 0;
  position: relative;
}

.button:last-child {
  margin-right: 0;
}

.button:active {
  bottom: -1px;
}

.button_type_all {
  background-color: var(--color-orange);
}

.button_type_flying {
  background-color: var(--color-sky);
}

.button_type_running {
  background-color: var(--color-brown);
}

.button_type_cat {
  background-color: var(--color-green);
}

.button_type_dog {
  background-color: var(--color-red);
}

.button_type_bird {
  background-color: var(--color-blue);
}


.container {
  display: flex;
  flex-wrap: wrap;
  max-width: 1024px;
  margin: 0 auto;
}

.card {
  width: calc(33.3333333% - 72px);
  margin: 36px;
  height: 200px;
  line-height: 200px;
  text-align: center;
  color: white;
  font-weight: bold;
  font-size: 48px;
  overflow: hidden;
  transition: 0.5s all;
}

.cat {
  background-color: var(--color-green);
}

.dog {
  background-color: var(--color-red);
}

.bird {
  background-color: var(--color-blue);
}

.anime {
  transform: scale(0);
  opacity: 0;
}

.hide {
  animation-name: hide;
  animation-duration: 0.5s;
  animation-fill-mode: forwards;
}

@keyframes hide {
  0% {
    visibility: visible;
    height: 200px;
  }
  100% {
    visibility: hidden;
    width: 0;
    height: 0;
    max-width: 0;
    font-size: 0;
    margin: 0;
  }
}

JS(实现层级切换与筛选逻辑)

function app() {
    const parentButtons = document.querySelectorAll('[data-parent]');
    const childFilterContainers = document.querySelectorAll('[data-parent-target]');
    const childButtons = document.querySelectorAll('.filter .button');
    const cards = document.querySelectorAll('.card');
    const allButton = document.querySelector('.button_type_all');

    // 显示指定父分类的子分类,隐藏其他
    function toggleChildCategories(parentId) {
        childFilterContainers.forEach(container => {
            if (container.dataset.parentTarget === parentId) {
                container.classList.remove('filter-hidden');
            } else {
                container.classList.add('filter-hidden');
            }
        });
        // 点击父分类时重置产品显示状态
        showAllCards();
    }

    // 显示所有产品卡片
    function showAllCards() {
        cards.forEach(card => {
            card.classList.remove('hide', 'anime');
        });
    }

    // 筛选产品逻辑
    function filter(category, items) {
        items.forEach((item) => {
            const isItemFiltered = !item.classList.contains(category);
            const isShowAll = category.toLowerCase() === 'all';
            if (isItemFiltered && !isShowAll) {
                item.classList.add('anime');
            } else {
                item.classList.remove('hide', 'anime');
            }
        });
    }

    // 父分类点击事件
    parentButtons.forEach(button => {
        button.addEventListener('click', () => {
            const parentId = button.dataset.parent;
            toggleChildCategories(parentId);
        });
    });

    // 子分类点击事件
    childButtons.forEach(button => {
        button.addEventListener('click', () => {
            const currentCategory = button.dataset.filter;
            filter(currentCategory, cards);
        });
    });

    // 全部按钮点击事件
    allButton.addEventListener('click', () => {
        showAllCards();
        // 隐藏所有子分类容器
        childFilterContainers.forEach(container => {
            container.classList.add('filter-hidden');
        });
    });

    // 动画结束后隐藏卡片
    cards.forEach((card) => {
        card.ontransitionend = function () {
            if (card.classList.contains('anime')) {
                card.classList.add('hide');
            }
        };
    });
}

app();

关键修改说明

  1. HTML关联设置:给父分类按钮加data-parent标识,子分类容器加data-parent-target关联对应父分类,产品卡片添加父分类类名(如running/flying),明确层级关系
  2. CSS隐藏控制:新增filter-hidden类实现子分类容器的默认隐藏
  3. JS逻辑补充:
    • 新增toggleChildCategories函数处理父分类点击后的子分类显示切换
    • 新增showAllCards函数重置产品显示状态
    • 拆分父/子分类的点击事件,分别处理层级切换与产品筛选
    • 修复全部按钮的逻辑,点击后隐藏所有子分类并显示全部产品

内容的提问来源于stack exchange,提问作者dbda6ef8f43b

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:35:23