WooCommerce多分类Ajax筛选后滚动加载更多功能失效问题求助
WooCommerce多分类筛选后加载无结果问题排查与解决
问题场景
为WooCommerce产品列表开发了滚动触发的Ajax加载更多、按分类筛选功能,整体正常,但存在异常:
- 仅在主商店页面,选择两个及以上分类筛选后,第一组产品正常显示,但滚动触发加载更多时,Ajax请求无返回结果;
- 分类列表页面执行相同操作完全正常;
- 单分类筛选在两个页面均正常。
排查核心原因
- 查询参数序列化错误:筛选功能返回的
$query->query_vars中,tax_query是WP_Tax_Query对象而非普通数组,PHP的json_encode无法正确序列化对象的私有/受保护属性,导致前端拿到的query_vars结构无效; - 主商店页面依赖tax_query:分类页面初始查询带
product_cat字符串参数,即使tax_query无效仍能生效;主商店页面无初始分类参数,完全依赖tax_query,因此失效; - 表单参数处理潜在问题:若分类复选框name为
category[],当前JS代码会保留键名中的[],导致PHP端无法通过$filters['category']获取筛选值。
解决方案
1. 修正筛选功能返回的查询参数
将筛选后返回的$query->query_vars替换为构建查询时的原始$args数组(纯数组结构,可正确序列化):
function mev_filter_products() { $args = json_decode(stripslashes($_POST['query']), true); $args['paged'] = 1; if (isset($_POST['filters'])) { $filters = $_POST['filters']; if (!isset($args['tax_query'])) { $args['tax_query'] = []; } if (isset($filters['category'])) { $args['tax_query'][] = [ 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => $filters['category'], 'operator' => 'IN', ]; } } $query = new WP_Query($args); ob_start(); if ($query->have_posts()) { while ($query->have_posts()) { $query->the_post(); get_template_part('woocommerce/content', 'product'); } } $html = ob_get_clean(); // 关键修改:返回原始$args数组而非$query->query_vars wp_send_json([ 'query_vars' => json_encode($args), 'html' => $html, ]); die(); } add_action('wp_ajax_filter_products', 'mev_filter_products'); add_action('wp_ajax_nopriv_filter_products', 'mev_filter_products');
2. 修正JS端表单参数处理
若分类复选框name为category[],移除键名末尾的[],确保PHP端能正确获取数组:
const defaultQueryVars = catalog_params.query_vars; let formData = $('#catalog-filters').serializeArray(); let filterData = { 'action' : 'filter_products', 'filters' : {}, 'query' : defaultQueryVars }; formData.forEach(item => { let key = item.name; // 移除键名末尾的[] if (key.endsWith('[]')) { key = key.slice(0, -2); if (!filterData.filters[key]) { filterData.filters[key] = []; } filterData.filters[key].push(item.value); } else { filterData.filters[key] = item.value; } }); $.ajax({ url: woocommerce_params.ajax_url, data: filterData, method: 'POST', success: function(data) { productList.html(data.html); currentPage = 1; queryVars = data.query_vars; } });
3. 加载更多请求防抖优化
避免滚动事件频繁触发请求,添加防抖处理:
let currentPage = catalog_params.current_page; let queryVars = catalog_params.query_vars; const productList = $('.catalog-page-list'); let isLoading = false; // 加载状态标记 function loadMoreProducts() { if (isLoading) return; isLoading = true; let data = { 'action' : 'load_more_products', 'query' : queryVars, 'page' : currentPage }; $.ajax({ url: woocommerce_params.ajax_url, data: data, method: 'POST', success: function(data) { if (data) { productList.find('.product-card:last-of-type').after(data); currentPage++; } }, complete: function() { isLoading = false; // 请求完成后重置状态 } }); } // 防抖函数 function debounce(func, delay) { let timer; return function() { clearTimeout(timer); timer = setTimeout(func, delay); }; } $(window).scroll(debounce(function () { if ($(document).scrollTop() > ($(document).height() - 2000)) { loadMoreProducts(); } }, 300));
内容的提问来源于stack exchange,提问作者Joint
相关产品推荐
相关产品推荐

