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

WooCommerce商品多属性批量选择加购功能实现咨询

WooCommerce 选色后多尺码批量加购实现方案

需求说明

  • 目标功能:用户先选定商品颜色,再自主勾选44、46、48等需要的尺码,一次性将选中的多规格商品加入购物车
  • 现有参考代码基于原生WooCommerce环境编写,原逻辑为全尺码一键加购,未做适配调整无法直接使用

现有参考代码问题梳理

现有代码为全尺码加购的半成品,核心逻辑是加载时读取商品所有变体ID,勾选全选框后通过AJAX把所有变体传入后端循环加购,存在以下问题导致无法运行、不符合需求:

  • 文件命名错误:主题函数文件标准命名为functions.php,代码标注为function.php,容易放错位置导致代码不生效
  • 脚本挂载错误:wp_localize_script将AJAX请求所需的全局变量挂载到了bootstrap脚本句柄下,实际AJAX逻辑写在自定义JS文件中,会导致前端报ajax_object is not defined的JS错误
  • 变体未做属性关联:直接读取商品下所有变体,没有和用户选中的颜色做绑定,会把其他颜色的尺码变体也加入购物车
  • 缺少单尺码勾选能力:仅提供全选复选框,没有单个尺码的勾选入口,不符合调整后的交互要求
  • 后端无校验逻辑:没有做请求合法性校验、变体归属校验、库存校验,容易出现加购失败、恶意请求问题
  • 交互体验生硬:加购成功后直接整页刷新,没有原生WooCommerce的加购提示、购物车局部更新效果

修正后实现代码

1. 主题functions.php代码

将以下代码加入当前主题/子主题的functions.php文件中:

// 加载前端所需脚本
function custom_bulk_cart_scripts() {
    // 如主题已加载bootstrap、popper可删除以下两行enqueue代码,避免重复加载
    wp_enqueue_script( 'popper-js', 'https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js', array( 'jquery' ), '1.14.7', true );
    wp_enqueue_script( 'bootstrap-js', 'https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js', array( 'jquery' ), '4.3.1', true );
    // 替换为你主题实际的JS文件存放路径
    wp_enqueue_script( 'custom-bulk-add-cart', get_stylesheet_directory_uri() . '/js/ajax_add_to_cart.js', array( 'jquery', 'wc-add-to-cart-variation' ), '1.0.0', true );
    // 传递AJAX请求所需参数到前端
    wp_localize_script( 'custom-bulk-add-cart', 'custom_ajax', 
        array(
            'url' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('bulk_add_cart_nonce')
        )
    ); 
} 
add_action( 'wp_enqueue_scripts', 'custom_bulk_cart_scripts' );

// 在可变商品加购按钮前渲染尺码勾选区域
add_action( 'woocommerce_before_add_to_cart_button', 'custom_size_checkbox_render', 10 );
function custom_size_checkbox_render() {
    global $product;
    if( !$product->is_type('variable') ) return;
    $available_variations = $product->get_available_variations();
    $grouped_variations = [];
    // 按颜色属性分组整理变体数据,供前端匹配
    foreach( $available_variations as $variation ) {
        // 如站点自定义了颜色/尺码属性slug,替换pa_color、pa_size为实际值
        $color = $variation['attributes']['attribute_pa_color'];
        $size = $variation['attributes']['attribute_pa_size'];
        $grouped_variations[$color][$size] = [
            'variation_id' => $variation['variation_id'],
            'is_in_stock' => $variation['is_in_stock'],
            'max_qty' => $variation['max_qty']
        ];
    }
    ?>
    <div class="custom-size-select-warp" data-variations='<?php echo wp_json_encode($grouped_variations); ?>'>
        <div class="size-checkbox-list" style="display:none;margin:15px 0;"></div>
        <div class="size-bulk-action" style="display:none;margin:10px 0;">
            <label style="margin-right:15px;">
                <input type="checkbox" class="check-all-size"> 全选当前颜色所有尺码
            </label>
            <button type="button" class="button bulk-add-to-cart-btn" disabled>批量加入购物车</button>
        </div>
    </div>
    <?php
}

// 批量加购AJAX处理接口
add_action('wp_ajax_custom_bulk_add_to_cart', 'custom_bulk_add_to_cart_handler' );
add_action('wp_ajax_nopriv_custom_bulk_add_to_cart', 'custom_bulk_add_to_cart_handler' );
function custom_bulk_add_to_cart_handler() {
    if( !isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'bulk_add_cart_nonce') ) {
        wp_send_json_error(['msg' => '非法请求']);
    }
    $product_id = intval($_POST['product_id']);
    $variation_ids = array_map('intval', explode(',', $_POST['variation_ids']));
    $qty = intval($_POST['qty']);
    if( !$product_id || !$variation_ids || $qty < 1 ) {
        wp_send_json_error(['msg' => '参数错误']);
    }
    $product = wc_get_product($product_id);
    if( !$product || !$product->is_type('variable') ) {
        wp_send_json_error(['msg' => '商品不存在']);
    }
    $available_variation_ids = $product->get_children();
    $added_count = 0;
    foreach( $variation_ids as $vid ) {
        if( !in_array($vid, $available_variation_ids) ) continue;
        $variation = wc_get_product($vid);
        if( !$variation->is_in_stock() ) continue;
        if( WC()->cart->add_to_cart($vid, $qty) ) {
            $added_count++;
        }
    }
    if( $added_count === 0 ) {
        wp_send_json_error(['msg' => '所选尺码无可用库存,加购失败']);
    }
    // 返回购物车碎片供前端局部更新
    ob_start();
    woocommerce_mini_cart();
    $mini_cart = ob_get_clean();
    $data = [
        'success' => true,
        'msg' => sprintf('成功将%d个尺码的商品加入购物车', $added_count),
        'fragments' => [
            'div.widget_shopping_cart_content' => '<div class="widget_shopping_cart_content">' . $mini_cart . '</div>'
        ]
    ];
    wp_send_json($data);
}

2. 前端JS代码(ajax_add_to_cart.js)

在主题目录下新建js/ajax_add_to_cart.js文件,写入以下代码:

jQuery(document).ready(function($){
    const $variationForm = $('.variations_form');
    const $sizeWarp = $('.custom-size-select-warp');
    const $sizeList = $sizeWarp.find('.size-checkbox-list');
    const $bulkAction = $sizeWarp.find('.size-bulk-action');
    const $checkAll = $bulkAction.find('.check-all-size');
    const $bulkBtn = $bulkAction.find('.bulk-add-to-cart-btn');
    const groupedVariations = $sizeWarp.data('variations');
    let currentColor = '';

    // 监听颜色选择完成事件
    $variationForm.on('found_variation', function(){
        // 替换#pa_color为站点实际的颜色选择器ID
        currentColor = $('select#pa_color').val();
        if( !currentColor || !groupedVariations[currentColor] ) {
            $sizeList.hide().empty();
            $bulkAction.hide();
            return;
        }
        // 渲染当前颜色下的可选尺码
        $sizeList.empty().show();
        const currentSizeGroup = groupedVariations[currentColor];
        $.each(currentSizeGroup, function(size, data){
            const disabled = data.is_in_stock ? '' : 'disabled';
            const stockTip = data.is_in_stock ? '' : '(无库存)';
            $sizeList.append(`
                <label style="margin-right:12px;${disabled?'color:#ccc;':''}">
                    <input type="checkbox" class="size-checkbox" value="${data.variation_id}" ${disabled}>
                    ${size} ${stockTip}
                </label>
            `);
        });
        $bulkAction.show();
        resetSelectStatus();
    });

    // 重置选择状态
    function resetSelectStatus(){
        $checkAll.prop('checked', false);
        $sizeList.find('.size-checkbox').prop('checked', false);
        $bulkBtn.prop('disabled', true);
    }

    // 单个尺码勾选事件
    $sizeList.on('change', '.size-checkbox', function(){
        const checkedCount = $sizeList.find('.size-checkbox:checked').length;
        $bulkBtn.prop('disabled', checkedCount === 0);
        const availableCount = $sizeList.find('.size-checkbox:not(:disabled)').length;
        $checkAll.prop('checked', checkedCount === availableCount);
    });

    // 全选逻辑
    $checkAll.on('change', function(){
        const isChecked = $(this).prop('checked');
        $sizeList.find('.size-checkbox:not(:disabled)').prop('checked', isChecked);
        $bulkBtn.prop('disabled', !isChecked);
    });

    // 批量加购提交
    $bulkBtn.on('click', function(){
        const checkedVids = [];
        $sizeList.find('.size-checkbox:checked').each(function(){
            checkedVids.push($(this).val());
        });
        if( checkedVids.length === 0 ) return;
        const qty = $('.quantity .input-text.qty').val() || 1;
        const productId = $variationForm.data('product_id');
        $.ajax({
            url: custom_ajax.url,
            type: 'POST',
            dataType: 'json',
            data: {
                action: 'custom_bulk_add_to_cart',
                nonce: custom_ajax.nonce,
                product_id: productId,
                variation_ids: checkedVids.join(','),
                qty: qty
            },
            beforeSend: function(){
                $bulkBtn.prop('disabled', true).text('加购中...');
            },
            success: function(res){
                if( res.success ) {
                    if( res.fragments ) {
                        $.each(res.fragments, function(selector, content){
                            $(selector).replaceWith(content);
                        });
                    }
                    $(document.body).trigger('added_to_cart', [res.fragments, null, null]);
                    alert(res.msg);
                    resetSelectStatus();
                } else {
                    alert(res.msg);
                }
            },
            complete: function(){
                $bulkBtn.text('批量加入购物车');
                const checkedCount = $sizeList.find('.size-checkbox:checked').length;
                $bulkBtn.prop('disabled', checkedCount === 0);
            }
        })
    });

    // 变体选择重置时隐藏尺码区域
    $variationForm.on('reset_data', function(){
        $sizeList.hide().empty();
        $bulkAction.hide();
        currentColor = '';
    })
})

部署注意事项

  • 代码中pa_color、pa_size为WooCommerce默认颜色、尺码属性的slug,如站点自定义过属性slug,需替换为实际值
  • JS文件路径需和wp_enqueue_script中配置的路径一致,否则脚本无法加载
  • 可根据主题实际样式调整复选框、按钮的CSS,适配页面视觉效果
  • 如主题已加载bootstrap、popper资源,删除functions.php中对应的重复加载代码

内容的提问来源于stack exchange,提问作者Benchmark Alchakov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:45:38