如何通过JS/jQuery实现带URL同步的商品颜色筛选功能?
jQuery实现带URL联动的颜色筛选功能
需求匹配说明
所有实现逻辑完全覆盖提出的功能要求:
- 单个复选框勾选时,仅展示匹配对应颜色的商品元素
- 多条件勾选时,自动展示所有符合任意已选颜色的元素(采用OR匹配规则,只要元素包含任意选中的颜色属性就显示)
- 点击「Show all」按钮时自动清空所有筛选状态,展示全部商品
- 筛选操作实时同步更新URL hash,严格遵循指定路径规则:选中单个红色为
#f/red、单个蓝色为#f/blue、同时选中红蓝色为#f/red/blue - 页面首次加载/刷新时,自动读取URL中的筛选参数,反向同步复选框选中状态并应用对应筛选规则
前置注意事项
原示例的HTML代码存在标签文本错位问题:原本对应蓝色的复选框后面的文本错写为绿色,对应绿色的复选框后面的文本错写为蓝色,直接使用会导致用户选择的颜色和实际匹配结果不对应,需先修正文本和value值保持一致。
完整实现代码
保留原有CSS代码
.filterelements { display: block; width: 210px; } .red, .green, .blue, .redgreen, .redblue { width: 50px; height: 50px; float: left; margin: 10px; } .red { background: #ff2600; } .green { background: #a5de00; } .blue { background: #0087ff; } .redgreen { background: rgb(255, 38, 0); background: linear-gradient(90deg, rgba(255, 38, 0, 1) 0%, rgba(165, 222, 0, 1) 100%); } .redblue { background: rgb(255, 38, 0); background: linear-gradient(90deg, rgba(255, 38, 0, 1) 0%, rgba(0, 135, 255, 1) 100%); }
修正后的基础HTML结构
<!DOCTYPE html> <html lang="zh-CN" dir="ltr"> <head> <meta charset="utf-8"> <title>颜色筛选示例</title> <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script> </head> <body> <button type="button" id="showAllBtn">Show all</button> <br> <input type="checkbox" name="red" value="red"> red <input type="checkbox" name="blue" value="blue"> blue <input type="checkbox" name="green" value="green"> green <hr /> <div class="filterelements"> <div class="red" rel="color:red"></div> <div class="green" rel="color:green"></div> <div class="blue" rel="color:blue"></div> <div class="redgreen" rel="color:red|color:green"></div> <div class="green" rel="color:green"></div> <div class="red" rel="color:red"></div> <div class="redblue" rel="color:red|color:blue"></div> </div> </body> </html>
核心jQuery逻辑实现
$(function() { // 初始化:解析每个商品元素的rel属性,把颜色标签存在自定义属性里,减少后续重复解析的性能消耗 $('.filterelements > div').each(function() { const colorStr = $(this).attr('rel') || ''; // 拆分rel里的color项,去掉color:前缀,得到当前元素关联的颜色数组 const colorList = colorStr.split('|') .map(item => item.replace('color:', '').trim()) .filter(item => item); $(this).data('colors', colorList); }); // 通用筛选应用方法,所有状态变化都走这个入口保证逻辑统一 function applyFilter() { // 获取所有已勾选的颜色值 const selectedColors = $('input[type="checkbox"]:checked') .map(function() { return $(this).val(); }) .get(); // 遍历所有元素做显隐控制 $('.filterelements > div').each(function() { const itemColors = $(this).data('colors') || []; // 无选中条件、或元素包含任意一个选中颜色时,展示元素 const shouldShow = selectedColors.length === 0 || itemColors.some(color => selectedColors.includes(color)); $(this).toggle(shouldShow); }); // 同步更新URL hash if (selectedColors.length === 0) { history.replaceState(null, '', window.location.pathname + window.location.search); } else { const hashPath = '#f/' + selectedColors.join('/'); history.replaceState(null, '', window.location.pathname + window.location.search + hashPath); } } // 复选框状态变化时触发筛选 $('input[type="checkbox"]').on('change', applyFilter); // Show all按钮绑定事件 $('#showAllBtn').on('click', function() { $('input[type="checkbox"]').prop('checked', false); applyFilter(); }); // 页面加载时读取URL hash,反向同步复选框状态 (function initFromUrl() { const hash = window.location.hash; if (hash.startsWith('#f/')) { // 拆分hash里的颜色参数 const urlColors = hash.replace('#f/', '').split('/').filter(item => item); // 同步复选框选中状态 urlColors.forEach(color => { $(`input[type="checkbox"][name="${color}"]`).prop('checked', true); }); // 应用筛选规则 applyFilter(); } })(); });
实现特点
- 采用
history.replaceState更新URL,不会在浏览器历史记录里堆积冗余的跳转步骤,不会出现用户点后退时反复跳转筛选状态的问题 - 元素匹配采用宽松OR规则:只要元素关联的颜色标签包含任意一个已选的筛选值,就会展示,不会出现多勾选后元素被误隐藏的问题
- 全链路状态同步:不管是修改复选框、点击「Show all」按钮、还是页面加载读取URL参数,都会调用统一的筛选方法,不会出现界面状态不同步的bug
内容的提问来源于stack exchange,提问作者Tomáš Siničák
相关产品推荐
相关产品推荐

