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
相关产品推荐
相关产品推荐

