如何通过JS/JQuery触发Liquid渲染,实现BigCartel商品分类筛选?
基于BigCartel Liquid实现商品分类筛选方案
因为Liquid是服务端预渲染(页面加载前就执行完毕),所以没法在客户端JS里直接调用Liquid生成新内容,下面给你两个实用的实现思路:
方案一:URL参数+服务端渲染(适合商品数量多的场景)
核心是通过URL查询参数让Liquid判断要渲染的商品集合,前端点击筛选时跳转/更新URL触发服务端重新渲染页面。
1. Liquid代码:根据URL参数渲染对应商品
<div class="product-list"> {% comment %} 获取URL里的filter参数 {% endcomment %} {% assign selected_category_handle = request.params.filter %} {% if selected_category_handle %} {% comment %} 根据handle找到对应的分类 {% endcomment %} {% assign target_category = categories | where: 'handle', selected_category_handle | first %} {% if target_category %} {% comment %} 渲染该分类下的商品 {% endcomment %} {% for product in target_category.products %} <div class="product"> <a href="{{ product.url }}">{{ product.name }}</a> <!-- 商品价格、图片等其他内容 --> </div> {% endfor %} {% else %} {% comment %} 分类不存在时显示全部商品 {% endcomment %} {% for product in products %} <div class="product"> <a href="{{ product.url }}">{{ product.name }}</a> </div> {% endfor %} {% endif %} {% else %} {% comment %} 无参数时显示全部商品 {% endcomment %} {% for product in products %} <div class="product"> <a href="{{ product.url }}">{{ product.name }}</a> </div> {% endfor %} {% endif %} </div>
2. 前端JS:点击筛选按钮更新URL
给筛选按钮绑定点击事件,修改URL的filter参数后跳转页面,服务端会自动根据新参数渲染对应商品:
// 假设每个筛选按钮的data-category属性存分类的handle document.querySelectorAll('li.filter').forEach(btn => { btn.addEventListener('click', function() { const categoryHandle = this.dataset.category; const currentUrl = new URL(window.location.href); if (categoryHandle) { currentUrl.searchParams.set('filter', categoryHandle); } else { // 点击「全部」时移除filter参数 currentUrl.searchParams.delete('filter'); } // 跳转到新URL,触发服务端重新渲染 window.location.href = currentUrl.toString(); }); });
方案二:提前渲染所有商品+前端JS切换显示(适合商品数量少的场景)
如果商品不多,可以让Liquid一次性渲染所有商品,前端通过JS控制显示/隐藏,避免页面刷新。
1. Liquid代码:给商品标记所属分类
<div class="product-list"> {% for product in products %} {% comment %} 给商品元素添加所属分类的data属性(多分类用空格分隔) {% endcomment %} {% assign category_handles = '' %} {% for category in product.categories %} {% assign category_handles = category_handles | append: category.handle | append: ' ' %} {% endfor %} <div class="product" data-categories="{{ category_handles | strip }}"> <a href="{{ product.url }}">{{ product.name }}</a> <!-- 商品其他内容 --> </div> {% endfor %} </div> <!-- 筛选按钮 --> <ul class="filter-group"> <li class="filter active" data-category="">全部</li> {% for category in categories %} <li class="filter" data-category="{{ category.handle }}">{{ category.name }}</li> {% endfor %} </ul>
2. 前端JS:控制商品显示/隐藏
const filters = document.querySelectorAll('.filter'); const products = document.querySelectorAll('.product'); filters.forEach(btn => { btn.addEventListener('click', function() { // 更新筛选按钮的选中状态 filters.forEach(item => item.classList.remove('active')); this.classList.add('active'); const targetCategory = this.dataset.category; products.forEach(product => { if (!targetCategory) { // 显示全部商品 product.style.display = 'block'; } else { // 只显示属于目标分类的商品 if (product.dataset.categories.includes(targetCategory)) { product.style.display = 'block'; } else { product.style.display = 'none'; } } }); }); });
内容的提问来源于stack exchange,提问作者GtwoK
相关产品推荐
相关产品推荐

