Фильтр категории-подкатегории-товары
Подскажите, пожалуйста, как сделать так чтобы при клике по категории появлялись её подкатегории (изначально не видны), а после клика по подкатегории уже фильтровались товары. Категории и подкатегории подтягиваются из БД. Сейчас получилось сделать только подкатегории и фильтрацию товаров. В JS полный ноль, всё собираю по кускам из сети. Помогите, пожалуйста.
Код у меня есть по ссылке: https://codepen.io/KuParty/pen/WNKPLbL Здесь тоже дублирую: HTML: Код:
<header class="header"> Код:
:root { function app() { const buttons = document.querySelectorAll('.button') const cards = document.querySelectorAll('.card') 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') item.classList.remove('anime') } }) } buttons.forEach((button) => { button.addEventListener('click', () => { const currentCategory = button.dataset.filter filter(currentCategory, cards) }) }) cards.forEach((card) => { card.ontransitionend = function () { if (card.classList.contains('anime')) { card.classList.add('hide') } } }) } app() Всё это сейчас прикручено к Jango таким образом: Код:
<header class="header-filter"> |
фильтр по категориям
KuParty,
<!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/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; } .filter-category { display: flex; justify-content: center; max-width: 1024px; margin: 0 auto; padding-bottom: 20px; } .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: 100px; line-height: 100px; 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; animation-delay: 0.6s; } @keyframes hide { 0% { visibility: visible; height: 200px; } 100% { visibility: hidden; width: 0; height: 0; max-width: 0; font-size: 0; margin: 0; } } </style> <script> document.addEventListener("DOMContentLoaded", function() { const header = document.querySelector('.header'); header.addEventListener("click", function({ target }) { if (target.closest('[data-filter]')) { let categorys = target.dataset.filter; const isShowAll = categorys == 'all' categorys = categorys.split(','); document.querySelectorAll('[data-filter]').forEach(elem => { let keys = elem.dataset.filter; const isKeyAll = keys == 'all'; keys = keys.split(','); const isItemFiltered = isKeyAll || isShowAll || keys.some(key => categorys.includes(key)); elem.classList.remove("hide"); elem.classList.toggle("anime", !isItemFiltered); if (!isItemFiltered) elem.classList.add("hide"); }) }; }) }) </script> </head> <body> <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-filter="cat,dog">Running</button> <button class="button button_type_flying" data-filter="bird">Flying</button> </div> <div class="filter"> <button class="button button_type_cat" data-filter="cat">Cat</button> <button class="button button_type_dog" data-filter="dog">Dog</button> <button class="button button_type_bird" data-filter="bird">Bird</button> </div> </header> <main class="content"> <div class="container"> <div class="card cat" data-filter="cat">Cat</div> <div class="card dog" data-filter="dog">Dog</div> <div class="card bird" data-filter="bird">Bird</div> <div class="card dog" data-filter="dog">Dog</div> <div class="card cat" data-filter="cat">Cat</div> <div class="card bird" data-filter="bird">Bird</div> <div class="card bird" data-filter="bird">Bird</div> <div class="card dog" data-filter="dog">Dog</div> <div class="card cat" data-filter="cat">Cat</div> </div> </main> </body> </html> |
рони
Спасибо за помощь. Но это немного не то. Я хотел чтобы все карточки и подкатегории DOG CAT BIRD изначально не были видны. После нажатия на категорию появлялись её подкатегории и карточки относящиеся к этим подкатегориям. При нажатии на подкатегорию фильтровались по ней. |
KuParty,
надо брать объект и отображать его текущее состояние, тогда будет что-то такое |
Цитата:
|
Цитата:
<!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <script> document.addEventListener("DOMContentLoaded", function() { const data = { child: { all: { child: { running: { child: { cat: { child: { cat1: { title: 'mmm' }, cat2: { title: 'ppp' } } }, dog: { child: { dog1: { title: 'rrr' }, dog2: { title: 'gav' } } } } }, flying: { child: { bird: { child: { bird1: { title: 'fly' } } } } } }, } }, show: true } const createHtml = data => { let ul = document.createElement('ul'); if (data.child) { for (let key in data.child) { let li = document.createElement('li'); li.textContent = key; ul.append(li); li.addEventListener("click", function(event) { event.preventDefault(); event.stopPropagation(); data.child[key].show = !data.child[key].show; create(); }) let el = data.child[key], show = data.child[key].show; if (typeof el == 'object' && show) li.append(createHtml(el)) } } if (data.title) { let li = document.createElement('li'); li.textContent = `my name is ${data.title}`; ul.append(li); } return ul } const create = () => { let html = createHtml(data); document.querySelector('.test').innerHTML = ''; document.querySelector('.test').append(html) } create() }) </script> </head> <body> <div class="test"></div> </body> </html> |
Часовой пояс GMT +3, время: 18:26. |