如何使用JS或jQuery实现带折叠分组的HTML卡片按标题过滤
卡片折叠分组过滤实现方案
原代码核心问题梳理
- 没有记录折叠分组的初始开合状态,在筛选"All"时强制把所有分组加上
show类展开,破坏了用户手动设置的折叠状态,完全不符合“原折叠分组保持折叠”的要求 - 只处理了当前处于展开状态的分组,没有对折叠状态下的分组内部卡片做过滤,会导致用户后续手动展开折叠分组时,看到未经过滤的全量卡片
- 通过多层DOM遍历(
firstElementChild嵌套)获取卡片标题的逻辑过于脆弱,只要HTML结构微调就会失效 - 直接修改className控制折叠开合,没有同步Bootstrap折叠组件的状态(比如面板按钮样式、
aria属性),容易出现UI状态错乱 - 依赖全局
event对象、内联onclick绑定事件的写法兼容性差,不符合规范
实现逻辑核心
- 页面初始化时,给每个折叠分组记录初始开合状态,过滤全程不修改这个初始值
- 不管分组当前是展开还是折叠,先对内部所有卡片按照筛选规则做显示/隐藏处理,保证任意状态下看到的都是过滤结果
- 严格按照规则调整分组开合状态:
- 原本就是折叠的分组:全程不改变开合状态,保持折叠
- 原本就是展开的分组:如果筛选后无匹配卡片,自动折叠;有匹配卡片则保持展开
- 切回"All"筛选时:所有卡片恢复显示,分组完全回到初始开合状态
具体代码调整
1. HTML部分小修改
把原下拉菜单的内联onclick去掉,改为通过自定义属性标记筛选值,方便事件绑定:
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <a class="dropdown-item" href="#" data-filter="All">All</a> <a class="dropdown-item" href="#" data-filter="Card1">Card1</a> <a class="dropdown-item" href="#" data-filter="Card2">Card2</a> <a class="dropdown-item" href="#" data-filter="Card3">Card3</a> </div>
2. JavaScript逻辑重写
用jQuery配合Bootstrap自带的折叠组件API实现,替换原有的FilterCard函数,新增初始化状态记录和事件绑定逻辑:
$(document).ready(function() { // 遍历所有折叠面板,记录初始开合状态 $('.collapse').each(function() { const $panel = $(this); $panel.data('initial-expanded', $panel.hasClass('show')); }) // 给筛选下拉项绑定点击事件 $('.dropdown-item[data-filter]').on('click', function(e) { e.preventDefault(); FilterCard($(this).data('filter')); }) }) function FilterCard(filter) { $('.collapse').each(function() { const $panel = $(this); const $cardContainer = $panel.find('.card-body').first(); const allCards = $cardContainer.find('.card'); let matchCount = 0; // 先处理所有卡片的显示/隐藏,不受面板开合状态影响 allCards.each(function() { const $card = $(this); const cardTitle = $card.find('.card-title').text().trim(); if (filter === 'All' || cardTitle === filter) { $card.show(); matchCount++; } else { $card.hide(); } }) const isInitialExpanded = $panel.data('initial-expanded'); if (filter === 'All') { // 切回全部时,严格保持分组初始开合状态 $panel.collapse(isInitialExpanded ? 'show' : 'hide'); } else { // 非全部筛选场景:只调整初始为展开状态的分组 if (isInitialExpanded) { // 无匹配项则自动折叠,有匹配则保持展开 $panel.collapse(matchCount > 0 ? 'show' : 'hide'); } // 初始为折叠的分组,完全不改变开合状态,保持折叠 } }) }
需求匹配验证
- 原本处于折叠状态的分组,无论选择哪个筛选值,都不会被强制展开,始终保持原有折叠状态,内部卡片提前完成过滤,用户手动展开时直接看到筛选结果
- 原本处于展开状态的分组,筛选后如果没有匹配的卡片,会自动折叠;有匹配卡片则保持展开,仅显示符合条件的卡片
- 筛选回"All"时,所有卡片恢复显示,分组完全回到页面初始加载时的开合状态,不会强制展开所有分组
内容的提问来源于stack exchange,提问作者user14492780
相关产品推荐
相关产品推荐

