WooCommerce可变商品数量增减直接修改购物车问题求助
WooCommerce可变商品数量按钮异常问题排查与修复
问题场景
使用WooCommerce可变商品时,用户选择规格后点击「加入购物车」可正常添加商品,但点击数量增减按钮时,会直接修改购物车中已存在的对应商品数量,需求是仅在点击「加入购物车」按钮后,才将对应数量的商品添加到购物车。
现有代码
子主题functions.php代码
add_action('wp_ajax_add_to_cart', 'ajax_add_to_cart'); add_action('wp_ajax_nopriv_add_to_cart', 'ajax_add_to_cart'); function ajax_add_to_cart() { check_ajax_referer('ajax_add_to_cart_nonce', 'nonce'); if (isset($_POST['product_id'])) { $product_id = intval($_POST['product_id']); WC()->cart->add_to_cart($product_id); die(); } } add_filter('woocommerce_add_to_cart_fragments', 'cart_fragments'); function cart_fragments($fragments) { ob_start(); ?> <span class="cart-contents"><?php echo WC()->cart->get_cart_contents_count(); ?></span> <?php $fragments['span.cart-contents'] = ob_get_clean(); return $fragments; }
自定义可变商品加入购物车模板代码
defined( 'ABSPATH' ) || exit; global $product; ?> <div class="woocommerce-variation-add-to-cart variations_button"> <?php do_action( 'woocommerce_before_add_to_cart_button' ); ?> <div class="quantity"> <label class="screen-reader-text" for="quantity_<?php echo esc_attr( $product->get_id() ); ?>">my-quantity</label> <div class="quantity_deel"> <div class="plus-min-btns"> <button onclick="decrementQuantity()">-</button> <input type="number" id="quantity_<?php echo esc_attr( $product->get_id() ); ?>" class="input-text qty text" name="quantity" value="1" aria-label="Product quantity" size="4" min="1" step="1" inputmode="numeric" autocomplete="off"> <button onclick="incrementQuantity()">+</button> </div> <div> <button type="submit" class="single_add_to_cart_button button alt<?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?>"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button> </div> </div> </div> <?php do_action( 'woocommerce_after_add_to_cart_button' ); ?> <input type="hidden" name="add-to-cart" value="<?php echo absint( $product->get_id() ); ?>" /> <input type="hidden" name="product_id" value="<?php echo absint( $product->get_id() ); ?>" /> <input type="hidden" name="variation_id" class="variation_id" value="0" /> </div> <script> function decrementQuantity() { var quantityInput = document.getElementById("quantity_<?php echo esc_attr( $product->get_id() ); ?>"); var currentValue = parseInt(quantityInput.value); if (currentValue > 1) { quantityInput.value = currentValue - 1; } } function incrementQuantity() { var quantityInput = document.getElementById("quantity_<?php echo esc_attr( $product->get_id() ); ?>"); var currentValue = parseInt(quantityInput.value); quantityInput.value = currentValue + 1; } </script>
问题原因分析
- WooCommerce默认行为干扰:数量输入框带有
qty类,WooCommerce的默认前端脚本会监听该类输入框的change事件,自动发起AJAX请求更新购物车中对应商品的数量,这就导致点击增减按钮修改输入框值后,直接触发了购物车数量更新。 - 自定义AJAX加入购物车函数不完整:当前
ajax_add_to_cart函数仅处理了product_id,未接收variation_id、商品属性和quantity参数,对于可变商品来说,这个AJAX函数实际并未生效,当前正常加入购物车依赖的是WooCommerce默认的表单提交逻辑。
修复方案
1. 阻止数量输入框的默认更新行为
修改模板中的输入框类名,移除qty类避免被默认脚本监听:
<input type="number" id="quantity_<?php echo esc_attr( $product->get_id() ); ?>" class="input-text custom-qty text" name="quantity" value="1" aria-label="Product quantity" size="4" min="1" step="1" inputmode="numeric" autocomplete="off">
2. 完善自定义AJAX加入购物车函数
更新functions.php中的ajax_add_to_cart函数,支持可变商品的参数传递:
function ajax_add_to_cart() { check_ajax_referer('ajax_add_to_cart_nonce', 'nonce'); $product_id = isset($_POST['product_id']) ? intval($_POST['product_id']) : 0; $quantity = isset($_POST['quantity']) ? intval($_POST['quantity']) : 1; $variation_id = isset($_POST['variation_id']) ? intval($_POST['variation_id']) : 0; $variation = isset($_POST['variation']) ? $_POST['variation'] : array(); if ($product_id && $variation_id) { // 可变商品加入购物车 WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variation); } elseif ($product_id) { // 简单商品加入购物车 WC()->cart->add_to_cart($product_id, $quantity); } // 返回购物车更新片段 WC_AJAX::get_refreshed_fragments(); die(); }
3. 替换默认表单提交为自定义AJAX
在模板的script标签中添加提交事件监听,用自定义AJAX替代默认提交逻辑:
document.querySelector('.single_add_to_cart_button').addEventListener('click', function(e) { e.preventDefault(); var productId = <?php echo $product->get_id(); ?>; var quantity = document.getElementById("quantity_<?php echo esc_attr( $product->get_id() ); ?>").value; var variationId = document.querySelector('.variation_id').value; var variation = {}; // 获取选中的规格属性 document.querySelectorAll('.variations select').forEach(function(select) { variation[select.name] = select.value; }); // 发起AJAX请求 fetch('<?php echo admin_url('admin-ajax.php'); ?>', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: 'action=add_to_cart&nonce=<?php echo wp_create_nonce("ajax_add_to_cart_nonce"); ?>&product_id=' + productId + '&quantity=' + quantity + '&variation_id=' + variationId + '&' + new URLSearchParams(variation).toString() }) .then(response => response.json()) .then(data => { // 更新购物车UI if (data.fragments) { Object.keys(data.fragments).forEach(function(key) { document.querySelector(key).innerHTML = data.fragments[key]; }); } }); });
内容的提问来源于stack exchange,提问作者Brango
相关产品推荐
相关产品推荐

