求助:将jQuery关联筛选按钮示例转为原生JavaScript实现
原生JavaScript实现关联筛选按钮
HTML结构
<!-- 主筛选按钮组 --> <div class="filter-group"> <button class="filter-btn active" data-category="all">全部</button> <button class="filter-btn" data-category="fruit">水果</button> <button class="filter-btn" data-category="vegetable">蔬菜</button> </div> <!-- 子筛选按钮组 --> <div class="sub-filter-group"> <button class="sub-filter-btn active" data-sub="all">全部</button> <button class="sub-filter-btn" data-sub="apple" data-parent="fruit">苹果</button> <button class="sub-filter-btn" data-sub="banana" data-parent="fruit">香蕉</button> <button class="sub-filter-btn" data-sub="carrot" data-parent="vegetable">胡萝卜</button> <button class="sub-filter-btn" data-sub="spinach" data-parent="vegetable">菠菜</button> </div> <!-- 待筛选的项目列表 --> <div class="items-container"> <div class="item" data-category="fruit" data-sub="apple">苹果</div> <div class="item" data-category="fruit" data-sub="banana">香蕉</div> <div class="item" data-category="vegetable" data-sub="carrot">胡萝卜</div> <div class="item" data-category="vegetable" data-sub="spinach">菠菜</div> <div class="item" data-category="fruit" data-sub="apple">红苹果</div> <div class="item" data-category="vegetable" data-sub="spinach">嫩菠菜</div> </div>
CSS样式
.filter-group, .sub-filter-group { margin: 1rem 0; } .filter-btn, .sub-filter-btn { padding: 0.5rem 1rem; margin-right: 0.5rem; border: none; border-radius: 4px; background: #e0e0e0; cursor: pointer; } .filter-btn.active, .sub-filter-btn.active { background: #2196f3; color: white; } .sub-filter-btn.hidden { display: none; } .items-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 1rem; } .item { padding: 1rem; background: #f5f5f5; border-radius: 4px; text-align: center; } .item.hidden { display: none; }
原生JavaScript逻辑
// 获取所有元素 const filterBtns = document.querySelectorAll('.filter-btn'); const subFilterBtns = document.querySelectorAll('.sub-filter-btn'); const items = document.querySelectorAll('.item'); // 主筛选点击事件 filterBtns.forEach(btn => { btn.addEventListener('click', () => { // 切换主按钮选中状态 filterBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); const selectedCategory = btn.dataset.category; // 筛选显示对应子按钮 subFilterBtns.forEach(subBtn => { if (selectedCategory === 'all' || subBtn.dataset.parent === selectedCategory || subBtn.dataset.sub === 'all') { subBtn.classList.remove('hidden'); } else { subBtn.classList.add('hidden'); } }); // 重置子筛选为"全部" const allSubBtn = document.querySelector('.sub-filter-btn[data-sub="all"]'); allSubBtn.classList.add('active'); subFilterBtns.forEach(b => b !== allSubBtn && b.classList.remove('active')); // 执行筛选 filterItems(selectedCategory, 'all'); }); }); // 子筛选点击事件 subFilterBtns.forEach(btn => { btn.addEventListener('click', () => { // 切换子按钮选中状态 subFilterBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); const selectedCategory = document.querySelector('.filter-btn.active').dataset.category; const selectedSub = btn.dataset.sub; // 执行筛选 filterItems(selectedCategory, selectedSub); }); }); // 核心筛选函数 function filterItems(category, sub) { items.forEach(item => { const itemCategory = item.dataset.category; const itemSub = item.dataset.sub; // 判断是否显示当前项目 const showCategory = category === 'all' || itemCategory === category; const showSub = sub === 'all' || itemSub === sub; item.classList.toggle('hidden', !(showCategory && showSub)); }); }
关键逻辑说明
- 用
data-*属性存储筛选关联规则,让按钮和项目的对应关系更直观 - 点击主筛选按钮时,自动过滤显示匹配的子筛选选项,同时重置子筛选状态
- 筛选函数同时校验主分类和子分类的选中条件,精准控制项目的显示/隐藏
- 通过
classList切换类名实现状态变化,替代jQuery的addClass/removeClass方法
内容的提问来源于stack exchange,提问作者nabi
相关产品推荐
相关产品推荐

