You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce多分类Ajax筛选后滚动加载更多功能失效问题求助

WooCommerce多分类筛选后加载无结果问题排查与解决

问题场景

为WooCommerce产品列表开发了滚动触发的Ajax加载更多、按分类筛选功能,整体正常,但存在异常:

  • 仅在主商店页面,选择两个及以上分类筛选后,第一组产品正常显示,但滚动触发加载更多时,Ajax请求无返回结果;
  • 分类列表页面执行相同操作完全正常;
  • 单分类筛选在两个页面均正常。

排查核心原因

  1. 查询参数序列化错误:筛选功能返回的$query->query_vars中,tax_query是WP_Tax_Query对象而非普通数组,PHP的json_encode无法正确序列化对象的私有/受保护属性,导致前端拿到的query_vars结构无效;
  2. 主商店页面依赖tax_query:分类页面初始查询带product_cat字符串参数,即使tax_query无效仍能生效;主商店页面无初始分类参数,完全依赖tax_query,因此失效;
  3. 表单参数处理潜在问题:若分类复选框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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 04:52:02