WooCommerce选择特定订单类型后配送方式隐藏后复现问题求助
解决WooCommerce结账页配送方式隐藏后重新显示的问题
问题说明
在WooCommerce结账页添加了自定义「订单类型」选择字段,需求是:
- 选择「到店用餐」或「到店自提」时,仅保留免费配送(ID:7)选项,隐藏其他配送方式
- 选择「配送上门」时,仅保留平邮(ID:6)选项,隐藏其他配送方式
但当前功能仅生效约1秒,结账页面加载/更新完成后,被隐藏的配送选项会重新显示。使用主题为Astra,相关代码如下:
// Add the custom field for "Order Type" add_action('woocommerce_checkout_billing', 'before_billing_fields', 5); function before_billing_fields() { $checkout = WC()->checkout; echo '<h3>' . __('Order Type', 'sdm') . '</h3>'; woocommerce_form_field('delivery_method', array( 'type' => 'select', 'options' => array( 'delivery' => __('Delivery', 'sdm'), 'dine_in' => __('Dine In', 'sdm'), 'pick_up' => __('Pick Up', 'sdm'), ), 'class' => array('delivery_method form-row-wide'), 'clear' => true, ), $checkout->get_value('delivery_method')); } // The jQuery script add_action( 'wp_footer', 'custom_checkout_script' ); function custom_checkout_script() { // Only on the checkout page if( ! is_checkout() && ! is_wc_endpoint_url( 'order-received' ) ) return; ?> <script type="text/javascript"> jQuery( function($){ var a = 'select#delivery_method', b = 'input[name^="shipping_method[0]"]', d = 'flat_rate:6', // Flat Rate ID e = 'free_shipping:7'; // Free Shipping ID // Function to set shipping method to Free Shipping function setFreeShipping() { $(b + '[value="' + e + '"]').prop("checked", true); $( document.body ).trigger( 'update_checkout' ); } // Function to set shipping method to Flat Rate function setFlatRate() { $(b + '[value="' + d + '"]').prop("checked", true); $( document.body ).trigger( 'update_checkout' ); } // Function to hide unselected shipping methods function hideUnselectedShipping() { var selectedMethod = $(b + ':checked').val(); $(b).each(function() { var id = $(this).val(); if (id != selectedMethod) { $(this).closest('li').hide(); } else { $(this).closest('li').show(); } }); } // Set the default delivery method to "Delivery" and trigger change event $(a).val('delivery').change(); hideUnselectedShipping(); // Live action event: On Select "delivery_method" change $(a).change( function () { if ($(this).val() == 'pick_up' || $(this).val() == 'dine_in') { setFreeShipping(); // Change to Free Shipping for Dine In or Pick Up } else { setFlatRate(); // Change to Flat Rate for Delivery } hideUnselectedShipping(); }); // Live action event: On Shipping method change $( 'form.checkout' ).on( 'change', b, function() { // If Free shipping is not selected, we change "delivery_method" select field to "post" if ($(this).val() != e) { $(a).val('delivery'); setFlatRate(); // Change to Flat Rate when another method is selected } hideUnselectedShipping(); }); }); </script> <?php }
问题原因
调用update_checkout后,WooCommerce会重新渲染配送方式区域,之前通过JS隐藏的元素会被重置显示,导致隐藏效果失效。
解决方案
添加对updated_checkout事件的监听,在结账页面更新完成后重新执行隐藏逻辑;同时调整默认值设置逻辑,避免重复触发不必要的更新。
修改后的完整代码:
// Add the custom field for "Order Type" add_action('woocommerce_checkout_billing', 'before_billing_fields', 5); function before_billing_fields() { $checkout = WC()->checkout; echo '<h3>' . __('Order Type', 'sdm') . '</h3>'; woocommerce_form_field('delivery_method', array( 'type' => 'select', 'options' => array( 'delivery' => __('Delivery', 'sdm'), 'dine_in' => __('Dine In', 'sdm'), 'pick_up' => __('Pick Up', 'sdm'), ), 'class' => array('delivery_method form-row-wide'), 'clear' => true, ), $checkout->get_value('delivery_method')); } // The jQuery script add_action( 'wp_footer', 'custom_checkout_script' ); function custom_checkout_script() { // Only on the checkout page if( ! is_checkout() && ! is_wc_endpoint_url( 'order-received' ) ) return; ?> <script type="text/javascript"> jQuery( function($){ var deliverySelect = 'select#delivery_method', shippingInputs = 'input[name^="shipping_method[0]"]', flatRateVal = 'flat_rate:6', // Flat Rate ID freeShippingVal = 'free_shipping:7'; // Free Shipping ID // Function to set shipping method to Free Shipping function setFreeShipping() { $(shippingInputs + '[value="' + freeShippingVal + '"]').prop("checked", true); $( document.body ).trigger( 'update_checkout' ); } // Function to set shipping method to Flat Rate function setFlatRate() { $(shippingInputs + '[value="' + flatRateVal + '"]').prop("checked", true); $( document.body ).trigger( 'update_checkout' ); } // Function to hide unselected shipping methods function hideUnselectedShipping() { var selectedMethod = $(shippingInputs + ':checked').val(); $(shippingInputs).each(function() { var id = $(this).val(); if (id != selectedMethod) { $(this).closest('li').hide(); } else { $(this).closest('li').show(); } }); } // Initialize on page load function initCheckout() { var currentDelivery = $(deliverySelect).val() || 'delivery'; // Set default if no value exists if (!$(deliverySelect).val()) { $(deliverySelect).val('delivery'); } // Set corresponding shipping method if (currentDelivery == 'pick_up' || currentDelivery == 'dine_in') { setFreeShipping(); } else { setFlatRate(); } } // Run initial setup initCheckout(); // Hide shipping methods after checkout updates $(document.body).on('updated_checkout', function() { hideUnselectedShipping(); }); // Live action event: On Select "delivery_method" change $(deliverySelect).change( function () { if ($(this).val() == 'pick_up' || $(this).val() == 'dine_in') { setFreeShipping(); } else { setFlatRate(); } }); // Live action event: On Shipping method change $( 'form.checkout' ).on( 'change', shippingInputs, function() { if ($(this).val() != freeShippingVal) { $(deliverySelect).val('delivery'); setFlatRate(); } }); }); </script> <?php }
关键修改点
- 新增
initCheckout函数处理页面加载时的默认值设置,避免重复触发change事件 - 添加
updated_checkout事件监听,在结账更新完成后自动调用hideUnselectedShipping,确保隐藏效果持续 - 变量名更具语义化,提升代码可读性
内容的提问来源于stack exchange,提问作者user3546314
相关产品推荐
相关产品推荐

