WooCommerce自定义AJAX产品筛选器开发求助
WooCommerce自定义AJAX产品筛选器开发求助
嘿,我来帮你梳理下实现这个AJAX尺寸筛选器的实战思路和关键步骤,都是我在项目里用过的靠谱方法:
第一步:在分类页面输出带库存校验的尺寸复选框
首先得在产品分类页的合适位置(比如侧边栏)生成尺寸筛选的复选框,而且只显示该分类下有库存产品对应的尺寸,避免用户选了没货的尺寸白忙活:
add_action('woocommerce_before_shop_loop', 'render_stocked_size_filters'); function render_stocked_size_filters() { // 只在产品分类页显示筛选器 if (!is_product_category()) return; $current_cat_id = get_queried_object_id(); // 替换成你实际的尺寸属性slug,WooCommerce默认属性前缀是pa_ $size_taxonomy = 'pa_size'; // 获取该分类下关联的尺寸属性(只保留有库存产品的尺寸) $sizes = get_terms(array( 'taxonomy' => $size_taxonomy, 'hide_empty' => true, 'meta_query' => array( array( 'key' => 'product_cat', 'value' => $current_cat_id, 'compare' => 'IN' ) ) )); if (!empty($sizes)) { echo '<div class="size-filter-wrap">'; echo '<h3>筛选尺寸</h3>'; echo '<form class="size-filter-form" data-category-id="' . $current_cat_id . '">'; foreach ($sizes as $size) { // 校验该尺寸是否有库存产品 $has_stock = wc_get_products(array( 'category' => array(get_term($current_cat_id)->slug), 'tax_query' => array( array( 'taxonomy' => $size_taxonomy, 'field' => 'slug', 'terms' => $size->slug ) ), 'stock_status' => 'instock', 'limit' => 1 // 只要存在至少1个有库存的就显示选项 )); if ($has_stock) { echo '<label class="size-filter-item"> <input type="checkbox" name="size_filters[]" value="' . esc_attr($size->slug) . '"> <span>' . esc_html($size->name) . '</span> </label>'; } } echo '</form></div>'; } }
第二步:编写AJAX交互的前端JS
给复选框绑定切换事件,用户勾选/取消时实时发送请求,替换产品列表内容:
jQuery(document).ready(function($) { // 监听尺寸复选框变化 $('.size-filter-form input[type="checkbox"]').on('change', function() { const selectedSizes = []; $('.size-filter-form input[type="checkbox"]:checked').each(function() { selectedSizes.push($(this).val()); }); const categoryId = $('.size-filter-form').data('category-id'); // 显示加载状态 $('.products').addClass('filter-loading'); // 发送AJAX请求 $.ajax({ url: wc_params.ajax_url, // 用WooCommerce自带的AJAX地址 type: 'POST', data: { action: 'filter_products_by_size', category_id: categoryId, selected_sizes: selectedSizes }, success: function(response) { if (response.success) { // 替换产品列表区域 $('.products').html(response.data).removeClass('filter-loading'); } else { $('.products').removeClass('filter-loading'); alert('筛选出错啦,刷新页面试试?'); } }, error: function() { $('.products').removeClass('filter-loading'); alert('网络有点问题,请稍后再试'); } }); }); });
第三步:后端处理AJAX请求并返回产品HTML
在主题的functions.php里写处理请求的函数,查询符合条件的产品并渲染成前端需要的HTML:
// 给登录/未登录用户都开放AJAX权限 add_action('wp_ajax_filter_products_by_size', 'handle_size_filter_ajax'); add_action('wp_ajax_nopriv_filter_products_by_size', 'handle_size_filter_ajax'); function handle_size_filter_ajax() { // 参数校验 if (!isset($_POST['category_id']) || !isset($_POST['selected_sizes'])) { wp_send_json_error('参数错误'); } $category_id = intval($_POST['category_id']); $selected_sizes = $_POST['selected_sizes']; $size_taxonomy = 'pa_size'; // 构建产品查询参数 $query_args = array( 'post_type' => 'product', 'posts_per_page' => wc_get_default_products_per_row() * wc_get_default_product_rows_per_page(), 'post_status' => 'publish', 'tax_query' => array( 'relation' => 'AND', // 限定当前分类 array( 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $category_id ) ), // 只显示有库存的产品 'meta_query' => array( array( 'key' => '_stock_status', 'value' => 'instock', 'compare' => '=' ) ) ); // 如果有选中的尺寸,添加尺寸筛选条件 if (!empty($selected_sizes)) { $query_args['tax_query'][] = array( 'taxonomy' => $size_taxonomy, 'field' => 'slug', 'terms' => $selected_sizes, 'operator' => 'IN' ); } // 查询产品 $products_query = new WP_Query($query_args); // 渲染产品HTML ob_start(); if ($products_query->have_posts()) { woocommerce_product_loop_start(); while ($products_query->have_posts()) { $products_query->the_post(); wc_get_template_part('content', 'product'); } woocommerce_product_loop_end(); } else { echo '<p class="no-products-found">没有找到符合条件的产品哦</p>'; } wp_reset_postdata(); $products_html = ob_get_clean(); wp_send_json_success($products_html); }
几个关键注意点
- 把代码里的
pa_size替换成你实际使用的尺寸属性slug(在WooCommerce后台「产品 > 属性」里能看到) - 如果你的主题产品列表容器类不是
products,要对应修改JS里的选择器 - 可以给
.filter-loading加个CSS加载动画,提升用户体验 - 测试时打开浏览器控制台,查看AJAX请求的参数和返回值,方便排查问题
备注:内容来源于stack exchange,提问作者Sreenath Kumar
相关产品推荐
相关产品推荐

