本文详解如何使用 shuffle.js 实现基于多个数据属性(如 solution、region 等)的动态联合过滤,避免单维度覆盖问题,支持任意扩展的多条件筛选逻辑。
本文详解如何使用 shuffle.js 实现基于多个数据属性(如 solution、region 等)的动态联合过滤,避免单维度覆盖问题,支持任意扩展的多条件筛选逻辑。
Shuffle.js 默认仅支持单一 filter 函数调用,但其核心能力在于:每次调用 shuffleInstance.filter(callback) 都会完全重置当前可见项,因此必须在所有筛选条件变更后,统一执行一次包含全部逻辑的过滤函数。你原始代码中分别在两个事件监听器里各自调用 filter(),不仅逻辑重复,更关键的是——未同步维护跨维度状态,导致 region 变更时 solution 状态丢失,反之亦然。
✅ 正确做法:集中管理筛选状态 + 单一过滤入口
推荐使用一个统一的状态对象(如 filters)存储各维度选中值,并封装 applyFilters() 方法,在任一筛选控件变更时触发该方法:
// 初始化筛选状态(默认全选)
const filters = {
solutions: [], // 如 ['Broiler Lighting', 'Layer Lighting']
regions: [] // 如 ['europe', 'us']
};
const shuffleInstance = new Shuffle(document.getElementById('product_grid'), {
itemSelector: '.product_grid_item',
buffer: 1,
});
// 统一过滤逻辑
function applyFilters() {
shuffleInstance.filter(element => {
const dataSolutions = JSON.parse(element.getAttribute('data-solutions') || '[]');
const dataRegions = JSON.parse(element.getAttribute('data-region') || '[]');
// 解析为小写以兼容大小写差异(可选)
const normalizedSolutions = dataSolutions.map(s => s.trim());
const normalizedRegions = dataRegions.map(r => r.toLowerCase().trim());
const matchesSolution = filters.solutions.length === 0 ||
filters.solutions.some(s => normalizedSolutions.includes(s));
const matchesRegion = filters.regions.length === 0 ||
filters.regions.some(r => normalizedRegions.includes(r.toLowerCase()));
return matchesSolution && matchesRegion;
});
}
// 绑定 solution 过滤(radio 按钮组)
jQuery('input[name="shuffle-filter"]').on('change', function () {
const value = this.value;
if (this.checked) {
// 单选模式:取消其他选项,只保留当前选中项(或支持多选?见下文说明)
filters.solutions = [value];
} else {
// 若需支持多选,请改用 checkbox 并移除此 else 分支
filters.solutions = [];
}
applyFilters();
});
// 绑定 region 过滤(radio 按钮组)
jQuery('input[name="region"]').on('change', function () {
filters.regions = [this.value]; // 同样按单选设计
applyFilters();
});
⚠️ 关键注意事项
- Radio 按钮 ≠ 多选:你当前使用的是 type="radio",天然互斥,因此 selectedSolutions 数组最多只含 1 项。若需支持「Broiler AND Layer」多选,请改用 type="checkbox",并调整 HTML 与 JS 逻辑(例如移除 checked="" 属性,监听 click 而非 change,手动 toggle 数组)。
- 数据格式一致性:确保 data-solutions 和 data-region 的 JSON 字符串严格符合语法(如双引号、无尾逗号),建议服务端输出时使用 json_encode() 或前端 JSON.stringify() 生成。
- 空值容错:添加 || '[]' 防止 getAttribute() 返回 null 导致 JSON.parse(null) 报错。
- 性能优化(可选):对大量元素(>500),可添加防抖(debounce)避免频繁重排;Shuffle 内置 throttle 选项亦可启用。
? 扩展性设计:轻松添加新维度
未来新增 category、priceRange 等维度?只需三步:
- 在 HTML 中添加对应控件(如
- 在 filters 对象中新增字段(category: '');
- 在 applyFilters() 的判断逻辑中追加匹配条件。
// 示例:增加 category 过滤
const matchesCategory = !filters.category ||
element.getAttribute('data-category') === filters.category;
return matchesSolution && matchesRegion && matchesCategory;
通过状态集中化 + 过滤逻辑解耦,Shuffle.js 完全胜任企业级多维筛选需求。记住核心原则:所有筛选条件共用同一 filter 函数,且每次变更后必须显式调用 shuffleInstance.filter() —— 这不是缺陷,而是赋予你完全控制权的设计哲学。











