WooCommerce属性筛选联动需求:实现多属性筛选关联更新
WooCommerce 属性筛选联动实现方案
核心逻辑
当用户选择任意属性筛选条件时,通过AJAX将当前所有已选条件发送到后端,查询符合条件的产品集合,再提取这些产品关联的其他属性可用选项,最后更新前端筛选控件和产品列表。
前端实现代码
jQuery(document).ready(function($) { // 监听所有筛选控件的变更事件 $('.woocommerce-widget-layered-nav input[type="checkbox"], .woocommerce-widget-layered-nav select').on('change', function() { const filters = {}; // 收集复选框类型的筛选条件 $('.woocommerce-widget-layered-nav input[type="checkbox"]:checked').each(function() { const tax = $(this).data('taxonomy'); if (!filters[tax]) filters[tax] = []; filters[tax].push($(this).val()); }); // 收集下拉框类型的筛选条件 $('.woocommerce-widget-layered-nav select').each(function() { const tax = $(this).attr('name').replace('filter_', ''); const val = $(this).val(); if (val) filters[tax] = [val]; }); // 发送AJAX请求到后端 $.ajax({ url: wc_params.ajax_url, type: 'POST', data: { action: 'get_filtered_attributes', filters: filters, shop_url: wc_params.ajax_url.replace('admin-ajax.php', '') }, success: function(response) { if (!response.success) return; // 更新每个属性筛选控件的选项 $.each(response.data.attributes, function(taxonomy, terms) { const $widget = $('.woocommerce-widget-layered-nav[data-taxonomy="' + taxonomy + '"]'); // 更新复选框列表 if ($widget.find('input[type="checkbox"]').length) { const $list = $widget.find('ul'); $list.empty(); $.each(terms, function(slug, name) { const isChecked = filters[taxonomy] && filters[taxonomy].includes(slug); const checkedAttr = isChecked ? 'checked="checked"' : ''; $list.append(`<li><label><input type="checkbox" ${checkedAttr} data-taxonomy="${taxonomy}" value="${slug}">${name}</label></li>`); }); } // 更新下拉框 if ($widget.find('select').length) { const $select = $widget.find('select'); $select.empty(); $select.append(`<option value="">所有${response.data.tax_labels[taxonomy]}</option>`); $.each(terms, function(slug, name) { const isSelected = filters[taxonomy] && filters[taxonomy].includes(slug); const selectedAttr = isSelected ? 'selected="selected"' : ''; $select.append(`<option ${selectedAttr} value="${slug}">${name}</option>`); }); } }); // 刷新产品列表 $('.products').html(response.data.products_html); } }); }); });
后端处理代码
将以下代码添加到主题的functions.php文件中:
add_action('wp_ajax_get_filtered_attributes', 'get_filtered_attributes'); add_action('wp_ajax_nopriv_get_filtered_attributes', 'get_filtered_attributes'); function get_filtered_attributes() { $filters = isset($_POST['filters']) ? $_POST['filters'] : []; $shop_url = isset($_POST['shop_url']) ? $_POST['shop_url'] : get_permalink(wc_get_page_id('shop')); // 构建产品查询参数 $args = [ 'post_type' => 'product', 'posts_per_page' => -1, 'post_status' => 'publish', 'tax_query' => ['relation' => 'AND'], ]; // 追加筛选条件到查询参数 foreach ($filters as $taxonomy => $terms) { $args['tax_query'][] = [ 'taxonomy' => $taxonomy, 'field' => 'slug', 'terms' => $terms, ]; } $products = new WP_Query($args); $product_ids = wp_list_pluck($products->posts, 'ID'); // 替换为你实际使用的属性分类名(WooCommerce属性默认前缀为pa_) $target_taxonomies = ['pa_country', 'pa_brand', 'pa_capacity']; $available_attributes = []; $tax_labels = []; foreach ($target_taxonomies as $taxonomy) { $tax_labels[$taxonomy] = get_taxonomy($taxonomy)->labels->name; // 查询当前产品集合关联的属性术语 $terms = get_terms([ 'taxonomy' => $taxonomy, 'object_ids' => $product_ids, 'hide_empty' => true, 'orderby' => 'name', 'order' => 'ASC', ]); $available_attributes[$taxonomy] = []; foreach ($terms as $term) { $available_attributes[$taxonomy][$term->slug] = $term->name; } } // 生成产品列表HTML ob_start(); if ($products->have_posts()) { woocommerce_product_loop_start(); while ($products->have_posts()) { $products->the_post(); wc_get_template_part('content', 'product'); } woocommerce_product_loop_end(); } else { echo '<p class="woocommerce-info">没有找到符合条件的产品</p>'; } wp_reset_postdata(); $products_html = ob_get_clean(); wp_send_json_success([ 'attributes' => $available_attributes, 'tax_labels' => $tax_labels, 'products_html' => $products_html, ]); wp_die(); }
注意事项
- 代码中的属性分类名需替换为你实际创建的属性(例如属性名为
country,对应分类名是pa_country) - 若使用缓存插件,需排除筛选页面的AJAX请求缓存,避免筛选结果不更新
- 产品数量较多时,建议修改
posts_per_page参数添加分页逻辑,防止查询性能下降 - 若你的筛选控件结构与默认WooCommerce不同,需调整前端代码中的选择器
内容的提问来源于stack exchange,提问作者7star
相关产品推荐
相关产品推荐

