如何在WooCommerce的form-billing.php中触发配送方式AJAX更新
WooCommerce 配送模块迁移后动态更新问题解决方案
问题说明
将WooCommerce结账页面的配送模块(wc_cart_totals_shipping_html())从review-order.php迁移到form-billing.php后,原有的jQuery('body').trigger('update_checkout')无法刷新新位置的配送区域。原因是WooCommerce默认AJAX更新逻辑仅针对结账页面特定区域(如#order_review),新添加的.shipping-container不在默认更新范围内。
解决方案
方案一:扩展WooCommerce更新片段(推荐)
通过过滤器将自定义配送容器加入AJAX更新的片段列表,让update_checkout事件自动刷新该区域。
- 添加PHP过滤器(主题functions.php)
add_filter('woocommerce_update_order_review_fragments', 'custom_shipping_fragment_update'); function custom_shipping_fragment_update($fragments) { ob_start(); if ( WC()->cart->needs_shipping() && WC()->cart->show_shipping() ) : ?> <div class="shipping-container"> <?php do_action( 'woocommerce_review_order_before_shipping' ); ?> <?php wc_cart_totals_shipping_html(); ?> <?php do_action( 'woocommerce_review_order_after_shipping' ); ?> </div> <?php endif; $fragments['.shipping-container'] = ob_get_clean(); return $fragments; }
- 更新form-billing.php中的JS代码
jQuery(document).ready(function($) { // 监听账单地址所有输入/选择框变化,触发结账更新 $('.woocommerce-billing-fields input, .woocommerce-billing-fields select').change(function() { $('body').trigger('update_checkout', {update_shipping_method: true}); }); // 验证更新状态(可选) $(document.body).on('updated_checkout', function() { console.log('配送区域已随账单信息更新'); }); });
方案二:手动AJAX请求更新
若方案一无法满足需求,可通过手动发起AJAX请求获取最新配送HTML并替换容器内容。
- 添加PHP AJAX处理(主题functions.php)
add_action('wp_ajax_get_shipping_methods', 'custom_get_shipping_methods'); add_action('wp_ajax_nopriv_get_shipping_methods', 'custom_get_shipping_methods'); function custom_get_shipping_methods() { // 更新客户账单地址会话数据 if (isset($_POST['billing_country'])) { WC()->customer->set_billing_country($_POST['billing_country']); WC()->customer->set_billing_state($_POST['billing_state'] ?? ''); WC()->customer->set_billing_postcode($_POST['billing_postcode'] ?? ''); WC()->customer->save(); // 重新计算配送选项 WC()->shipping->calculate_shipping(); } // 生成最新配送HTML ob_start(); if ( WC()->cart->needs_shipping() && WC()->cart->show_shipping() ) : do_action( 'woocommerce_review_order_before_shipping' ); wc_cart_totals_shipping_html(); do_action( 'woocommerce_review_order_after_shipping' ); endif; $shipping_html = ob_get_clean(); wp_send_json_success(array('shipping_html' => $shipping_html)); }
- 更新form-billing.php中的JS代码
jQuery(document).ready(function($) { $('.woocommerce-billing-fields input, .woocommerce-billing-fields select').change(function() { // 序列化结账表单数据 var formData = $('form.checkout').serialize(); $.ajax({ url: wc_checkout_params.wc_ajax_url.replace('%%endpoint%%', 'get_shipping_methods'), type: 'POST', data: formData, success: function(response) { if (response.data.shipping_html) { $('.shipping-container').html(response.data.shipping_html); // 触发配送方法更新事件,确保交互正常 $(document.body).trigger('updated_shipping_method'); } } }); }); });
注意事项
- 确保
form-billing.php中的配送容器类名为.shipping-container,与代码中的选择器一致。 - 修改后清空浏览器缓存及网站缓存,避免旧代码干扰。
- 若使用方案一,需确保没有其他脚本阻止
update_checkout事件的触发。
内容的提问来源于stack exchange,提问作者Black Cat
相关产品推荐
相关产品推荐

