如何实现点击分类显示子分类,点击子分类后通过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();
关键修改说明
- HTML关联设置:给父分类按钮加
data-parent标识,子分类容器加data-parent-target关联对应父分类,产品卡片添加父分类类名(如running/flying),明确层级关系 - CSS隐藏控制:新增
filter-hidden类实现子分类容器的默认隐藏 - JS逻辑补充:
- 新增
toggleChildCategories函数处理父分类点击后的子分类显示切换 - 新增
showAllCards函数重置产品显示状态 - 拆分父/子分类的点击事件,分别处理层级切换与产品筛选
- 修复全部按钮的逻辑,点击后隐藏所有子分类并显示全部产品
- 新增
内容的提问来源于stack exchange,提问作者dbda6ef8f43b
相关产品推荐
相关产品推荐

