You need to enable JavaScript to run this app. 如何使用JS或jQuery实现带折叠分组的HTML卡片按标题过滤
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.03 23:27:03