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

WooCommerce Blocks结账页添加希腊专属动态免运费提示遇插件时机问题

WooCommerce Blocks结账页添加希腊专属免运费提示文本问题解决

需求说明

  • 在WooCommerce Blocks结账页面的配送方式列表下方添加动态提示文本(示例:"Add x € to your basket to receive free shipping!")
  • 仅当配送国家为希腊时显示该文本
  • 根据URL路径切换希腊语、英语、德语三种语言版本

原实现问题

编写的JavaScript代码在浏览器控制台运行正常,但封装为WordPress插件后因执行时机不匹配无法生效:

原插件PHP代码

<?php
/**
 * Plugin Name: Custom Shipping Note Greece
 * Description: Shows a free shipping message on WooCommerce checkout when shipping to Greece, with GR/EN/DE support.
 * Version: 1.0
 * Author: xxxx
 * Text Domain: custom-shipping-note-greece
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

add_action( 'wp_footer', function() {
    if ( ! function_exists( 'is_checkout' ) ) return;
    if ( ! is_checkout() || is_order_received_page() ) return;

    ?>
    <style>
    #free-shipping-note {
        margin-top: 12px;
        font-weight: 600;
        font-size: 14px;
        color: #1a1a1a;
    }
    #free-shipping-note.muted { color: #666; font-weight: 500; }
    </style>

    <script>
        
        /* .js SCRIPT GOES HERE*/

    </script>
    <?php
});

原JavaScript代码

(function(){
    const FREE_THRESHOLD = 50;

    const LANG_TEXTS = {
        gr: {
            calculating: 'Υπολογισμός διαφοράς δωρεάν αποστολής...',
            free: 'Δικαιούστε δωρεάν αποστολή!',
            add: diff => 'Προσθέστε ' + diff + ' στο καλάθι σας για να λάβετε δωρεάν αποστολή!'
        },
        en: {
            calculating: 'Calculating free-shipping difference...',
            free: 'You qualify for free shipping!',
            add: diff => 'Add ' + diff + ' to your basket to receive free shipping!'
        },
        de: {
            calculating: 'Berechnung des kostenlosen Versandunterschieds...',
            free: 'Sie qualifizieren sich für kostenlosen Versand!',
            add: diff => 'Fügen Sie ' + diff + ' Ihrem Warenkorb hinzu, um kostenlosen Versand zu erhalten!'
        }
    };

    function getLang(){
        const path = window.location.pathname;
        if (path.startsWith('/en/')) return 'en';
        if (path.startsWith('/de/')) return 'de';
        return 'gr';
    }

    function formatMoney(num){
        return Number(num).toFixed(2).replace('.', ',') + ' €';
    }

    function getSubtotal(){
        const rows = document.querySelectorAll('.wc-block-components-totals-item');
        for (let row of rows){
            const label = row.querySelector('.wc-block-components-totals-item__label');
            const valueEl = row.querySelector('.wc-block-components-totals-item__value');
            if (!label || !valueEl) continue;
            if (label.textContent.trim() === 'Υποσύνολο' || label.textContent.trim() === 'Subtotal' || label.textContent.trim() === 'Zwischensumme'){
                const text = valueEl.textContent.replace(/[^\d,\.]/g,'');
                const val = text.replace('.', '').replace(',', '.');
                return parseFloat(val) || 0;
            }
        }
        return 0;
    }

    function getShippingCountry(){
        const shippingEl = document.querySelector('#shipping-country');
        if (shippingEl) return shippingEl.value.toUpperCase();
        const billingEl = document.querySelector('#billing-country');
        return billingEl ? billingEl.value.toUpperCase() : null;
    }

    function insertNote(){
        const shippingContainer = document.querySelector('.wc-block-components-shipping-rates-control');
        if (!shippingContainer) return null;

        let note = document.querySelector('#free-shipping-note');
        if (!note){
            note = document.createElement('div');
            note.id = 'free-shipping-note';
            note.style.marginTop = '12px';
            note.style.fontWeight = '600';
            note.style.fontSize = '14px';
            shippingContainer.insertAdjacentElement('afterend', note);
        }
        return note;
    }

    function updateNote(){
        const lang = getLang();
        const country = getShippingCountry();
        if (country !== 'GR'){
            const note = document.querySelector('#free-shipping-note');
            if (note) note.style.display = 'none';
            return;
        }

        const note = insertNote();
        if (!note) return;
        note.style.display = 'block';

        const subtotal = getSubtotal();
        if (!subtotal) {
            note.textContent = LANG_TEXTS[lang].calculating;
            return;
        }

        if (subtotal >= FREE_THRESHOLD){
            note.textContent = LANG_TEXTS[lang].free;
        } else {
            const diff = FREE_THRESHOLD - subtotal;
            note.textContent = LANG_TEXTS[lang].add(formatMoney(diff));
        }
    }

    function observeChanges(){
        const shippingContainer = document.querySelector('.wc-block-components-shipping-rates-control');
        if (shippingContainer){
            const observer = new MutationObserver(updateNote);
            observer.observe(shippingContainer, {childList:true, subtree:true});
        }

        const shippingEl = document.querySelector('#shipping-country');
        if (shippingEl) shippingEl.addEventListener('change', updateNote);

        const billingEl = document.querySelector('#billing-country');
        if (billingEl) billingEl.addEventListener('change', updateNote);

        const sameAsBilling = document.querySelector('#ship-to-different-address-checkbox');
        if (sameAsBilling) sameAsBilling.addEventListener('change', updateNote);
    }

    const interval = setInterval(()=>{
        if (document.querySelector('.wc-block-components-shipping-rates-control')){
            clearInterval(interval);
            observeChanges();
            updateNote();
        }
    }, 200);

})();

正确解决方案

由于WooCommerce Blocks基于React的渲染机制,传统wp_footer注入脚本的方式无法准确匹配DOM加载与数据更新时机,正确方案是构建WooCommerce结账块扩展,核心实现思路:

  1. 注册自定义块扩展,挂载到结账页面的配送费率控件区域
  2. 利用WooCommerce官方提供的状态管理API,监听购物车小计、配送国家等核心数据变化
  3. 根据当前语言(从URL路径判断)和配送国家,动态渲染对应的免运费提示文本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 21:44:51