WooCommerce中Local Pickup配送方式添加选择框功能实现问题
问题分析
你的代码确实能在自提配送方式下方输出门店选择框,但缺少了配送方式切换的监听逻辑——PHP是服务器端渲染,页面加载时就把选择框输出了,不管当前选中的是哪种配送方式,所以它会一直显示。要实现"选中自提才显示,切回固定费率就隐藏"的效果,得靠JS来控制显示状态,同时还要处理页面初始化时的默认隐藏。
修复方案
下面是修改后的完整代码,主要做了这几点:
- 给门店选择框套了个容器,初始设为隐藏
- 新增了配送方式切换的监听逻辑,实时判断选中的配送方式来显示/隐藏选择框
- 处理了页面加载时的初始状态,匹配默认的固定费率隐藏选择框
function add_custom_select_box($method, $index) { if ($method->method_id == 'local_pickup') { // 新增容器,初始隐藏 echo '<div class="local-pickup-store-select" style="display:none; margin-top:10px;">'; echo '<select name="local_pickup_store" id="local_pickup_store" onchange="updateSelectedStore()"> <option value="choose_store">选择门店</option> <option value="store1">门店1</option> <option value="store2">门店2</option> </select>'; echo '<div id="selected_store_info"></div>'; echo '</div>'; } } add_action('woocommerce_after_shipping_rate', 'add_custom_select_box', 10, 2); function save_local_pickup_store($order) { if (isset($_POST['local_pickup_store'])) { $local_pickup_store = sanitize_text_field($_POST['local_pickup_store']); $order->update_meta_data('_local_pickup_store', $local_pickup_store); } } add_action('woocommerce_checkout_create_order', 'save_local_pickup_store'); function display_local_pickup_store($order) { $local_pickup_store = $order->get_meta('_local_pickup_store'); if ($local_pickup_store) { echo '<p><strong>自提门店:</strong> ' . esc_html($local_pickup_store) . '</p>'; } } add_action('woocommerce_admin_order_data_after_billing_address', 'display_local_pickup_store'); add_action('wp_footer', 'custom_local_pickup_script'); function custom_local_pickup_script() { // 只在 checkout 页面加载脚本 if (!is_checkout()) return; ?> <script> document.addEventListener('DOMContentLoaded', function() { // 获取所有配送方式的单选按钮 const shippingRadios = document.querySelectorAll('input[name^="shipping_method"]'); // 获取门店选择容器 const storeSelectContainer = document.querySelector('.local-pickup-store-select'); // 定义切换逻辑函数 function toggleStoreSelect() { // 找到选中的配送方式 const selectedMethod = document.querySelector('input[name^="shipping_method"]:checked'); if (selectedMethod) { // 判断是否是自提方式(兼容带实例ID的格式,比如local_pickup:1) const isLocalPickup = selectedMethod.value.includes('local_pickup'); storeSelectContainer.style.display = isLocalPickup ? 'block' : 'none'; } } // 页面加载时执行一次,处理初始状态 toggleStoreSelect(); // 给每个单选按钮绑定点击事件 shippingRadios.forEach(radio => { radio.addEventListener('change', toggleStoreSelect); }); }); function updateSelectedStore() { var selectedStore = document.getElementById('local_pickup_store').value; var selectedStoreInfo = document.getElementById('selected_store_info'); if (selectedStore !== 'choose_store') { selectedStoreInfo.innerHTML = '<p><strong>已选门店:</strong> ' + selectedStore + '</p>'; } else { selectedStoreInfo.innerHTML = ''; } } </script> <?php }
额外说明
- 脚本里加了
is_checkout()判断,避免在其他页面加载不必要的JS - 用
selectedMethod.value.includes('local_pickup')判断,兼容WooCommerce可能的配送方式ID格式(比如带实例ID的local_pickup:1) - 给容器加了margin-top,优化和上方配送方式的间距
内容的提问来源于stack exchange,提问作者jackievon51
相关产品推荐
相关产品推荐

