You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce按分类筛选商品归集为数组实现GSAP筛选动画

同分类商品归集+GSAP筛选动画实现方案

这个需求完全可实现,核心是通过匹配类名前缀识别分类标识,不需要依赖类名的固定位置,适配WooCommerce商品类名顺序不固定的场景。


核心实现思路

WooCommerce商品的分类类名统一以product_cat-为前缀,不需要像之前弹窗逻辑那样找固定索引的类名,直接遍历商品项匹配前缀即可提取分类标识,再按标识把商品归集到对应分组,后续直接调用分组结果配合GSAP做动画即可。


第一步:按分类归集商品

你可以直接用下面的代码完成归集,兼容你当前用的jQuery环境(WooCommerce默认加载jQuery):

// 初始化分类存储对象,key为分类标识,value为对应分类的商品DOM数组
const categoryProducts = {};

// 遍历所有带分类标识的商品项
$('ul li[class*="product_cat-"]').each(function() {
  const $currentProduct = $(this);
  // 拆分当前商品的所有类名为数组,兼容多个类名之间的多空格、换行情况
  const classArr = $currentProduct.attr('class').split(/\s+/);
  // 匹配product_cat-开头的分类类名
  const targetCatClass = classArr.find(cls => cls.startsWith('product_cat-'));
  if (!targetCatClass) return;

  // 提取分类标识,比如product_cat-category-1提取后得到category-1
  const catSlug = targetCatClass.replace('product_cat-', '');
  // 把当前商品存入对应分类分组,存原生DOM方便GSAP直接操作
  if (!categoryProducts[catSlug]) categoryProducts[catSlug] = [];
  categoryProducts[catSlug].push($currentProduct[0]);
});

归集完成后直接通过categoryProducts['category-1']就能拿到分类1下的所有商品DOM数组,GSAP可以直接传入这个数组做动画。
如果需要拼接选择器字符串,直接用.product_cat-${catSlug}格式即可,不需要提前归集也能直接选中对应分类商品。


第二步:配合GSAP实现WooCommerce商品筛选动画

下面是可直接用的完整示例,包含筛选按钮、结果容器、动画逻辑,适配你要求的「追加到新div」的需求:

1. 页面结构(可放到WooCommerce商品列表模板对应位置)

<!-- 分类筛选按钮组 -->
<div class="woo-product-filter">
  <button class="filter-btn active" data-cat="all">全部分类</button>
  <button class="filter-btn" data-cat="category-1">分类1</button>
  <button class="filter-btn" data-cat="category-2">分类2</button>
  <button class="filter-btn" data-cat="category-3">分类3</button>
  <button class="filter-btn" data-cat="category-4">分类4</button>
  <button class="filter-btn" data-cat="category-5">分类5</button>
</div>
<!-- 筛选后商品展示容器 -->
<div class="filtered-product-container"></div>
<!-- 原WooCommerce商品列表,可根据需求隐藏或者保留 -->
<ul class="wc-original-product-list">
  <!-- 此处为WooCommerce自动输出的商品li结构,和你贴的代码一致 -->
</ul>

2. JS逻辑(放到主题自定义JS代码段里即可)

$(document).ready(function() {
  const $originalList = $('.wc-original-product-list');
  const $filterContainer = $('.filtered-product-container');
  const $filterBtns = $('.woo-product-filter .filter-btn');
  const categoryProducts = {};

  // 初始化归集商品
  $originalList.find('li[class*="product_cat-"]').each(function() {
    const classArr = $(this).attr('class').split(/\s+/);
    const catClass = classArr.find(cls => cls.startsWith('product_cat-'));
    if (!catClass) return;
    const catSlug = catClass.replace('product_cat-', '');
    if (!categoryProducts[catSlug]) categoryProducts[catSlug] = [];
    // 克隆节点时传true,保留原元素绑定的加购、快速查看等事件,避免功能失效
    categoryProducts[catSlug].push($(this).clone(true)[0]);
  });

  // 渲染对应分类商品+GSAP动画
  function renderFilteredProducts(targetCat = 'all') {
    // 先对当前显示的商品做离场动画
    gsap.to($filterContainer.children(), {
      opacity: 0,
      y: 15,
      duration: 0.25,
      stagger: 0.04,
      onComplete: () => {
        $filterContainer.empty();
        // 组装要显示的商品数组
        let showProducts = [];
        if (targetCat === 'all') {
          Object.values(categoryProducts).forEach(products => {
            showProducts = showProducts.concat(products);
          });
        } else {
          showProducts = categoryProducts[targetCat] || [];
        }
        // 把商品追加到新容器
        showProducts.forEach(product => $filterContainer.append(product));
        // 执行入场动画
        gsap.fromTo(showProducts,
          { opacity: 0, y: 15 },
          { opacity: 1, y: 0, duration: 0.35, stagger: 0.06, ease: "power2.out" }
        );
      }
    })
  }

  // 初始加载显示全部商品
  renderFilteredProducts('all');

  // 绑定筛选按钮点击事件
  $filterBtns.on('click', function() {
    const currentCat = $(this).data('cat');
    $filterBtns.removeClass('active');
    $(this).addClass('active');
    renderFilteredProducts(currentCat);
  })
})

场景适配注意事项

  • 如果你的商品列表开启了Ajax分页、无限滚动,需要在Ajax加载完成的回调里重新执行一次商品归集逻辑,否则新加载的商品不会被收录到分组里。
  • 如果你不想提前归集商品,完全可以直接用CSS选择器实时查询,比如选中分类1的商品直接用$('li.product_cat-category-1'),写法更简单,分类数量不多的场景下性能完全足够,示例:
    // 实时查询写法,不需要提前初始化categoryProducts
    function renderFilteredProducts(targetCat = 'all') {
      const selector = targetCat === 'all' ? 'li[class*="product_cat-"]' : `li.product_cat-${targetCat}`;
      const showProducts = $originalList.find(selector).clone(true);
      // 后续动画、追加逻辑和上面一致
    }
    
  • 不要用之前按类名固定索引取值的方式,WooCommerce的商品类名顺序会被主题、插件修改,固定索引的写法很容易失效,匹配product_cat-前缀的方式不受类名顺序影响,兼容性更好。

内容的提问来源于stack exchange,提问作者Tarun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:06:09