Woocommerce Blocks购物车商品数量变更触发分析事件异常求助
Woocommerce Blocks购物车数量变更事件追踪解决方案
问题背景
- 需求:购物车内商品数量变更时,向分析系统发送对应事件
- 困境:使用Woocommerce Blocks,无法通过标准Woocommerce钩子实现;尝试MutationObserver方案但事件未触发
调整后的可行方案及代码
核心优化点
- 扩展MutationObserver监听范围,包含属性变更(尤其是输入框的value属性)
- 改用
input事件监听数量输入框,适配点击增减按钮的场景 - 添加防抖逻辑,避免重复触发事件
- 优化DOM选择器,适配Woocommerce Blocks的动态渲染特性
修改后的完整代码
function track_cart_quantity_change_js() { ?> <script type="text/javascript"> jQuery(document).ready(function($) { console.log('track_cart_quantity_change_js loading'); // 防抖函数,避免重复触发 function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } // 记录当前购物车状态,用于对比是否真的变更 let currentCartState = {}; function getCartState() { const state = {}; $('.wc-block-cart-items__row').each(function() { const $row = $(this); const product_id = new URL($row.find('.wc-block-components-product-name').attr('href')).pathname.split('/').filter(Boolean).pop(); const quantity = parseInt($row.find('input.wc-block-components-quantity-selector__input').val()); state[product_id] = quantity; }); return state; } function initCartObserver() { const cartElement = document.querySelector('.wp-block-woocommerce-cart'); // 适配最新Blocks容器类名 if (cartElement) { console.log('购物车容器已找到,启动观察者'); const debouncedUpdate = debounce(updateCartItems, 300); const observer = new MutationObserver(function(mutations) { let shouldUpdate = false; mutations.forEach(function(mutation) { // 监听子元素变化或输入框value属性变化 if (mutation.type === 'childList' || (mutation.type === 'attributes' && mutation.attributeName === 'value' && mutation.target.classList.contains('wc-block-components-quantity-selector__input'))) { shouldUpdate = true; } }); if (shouldUpdate) { debouncedUpdate(); } }); observer.observe(cartElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['value'] // 只监听value属性变更 }); } else { console.log('未找到购物车容器,500ms后重试'); setTimeout(initCartObserver, 500); } } function updateCartItems() { const newState = getCartState(); // 对比状态,只有数量真的变化才发送事件 if (JSON.stringify(newState) !== JSON.stringify(currentCartState)) { currentCartState = newState; $('.wc-block-cart-items__row').each(function() { const $row = $(this); const product_url = $row.find('.wc-block-components-product-name').attr('href'); const product_id = new URL(product_url).pathname.split('/').filter(Boolean).pop(); const product_name = $row.find('.wc-block-components-product-name').text().trim(); const product_quantity = parseInt($row.find('input.wc-block-components-quantity-selector__input').val()); const product_price = $row.find('.wc-block-cart-item__total .wc-block-formatted-money-amount').text().trim().replace(/[^0-9.,]/g, '').replace(',', '.'); const product_brand = ''; const product_category = ''; const product_variant = $row.find('.wc-block-components-product-details__value').text().trim(); const productData = { id: product_id, name: product_name, brand: product_brand, category: product_category, variant: product_variant, quantity: product_quantity, price: product_price }; sendCartUpdateEvent(productData); }); } } function sendCartUpdateEvent(productData) { console.log('发送购物车更新事件:', productData); window.dataLayer = window.dataLayer || []; dataLayer.push({ ecommerce: null }); dataLayer.push({ 'event': 'addToCart', 'ecommerce': { 'currencyCode': 'EUR', 'add': { 'products': [productData] } } }); } initCartObserver(); // 监听数量输入框的input事件(适配点击增减按钮的场景) $(document).on('input', '.wc-block-components-quantity-selector__input', function() { console.log('购物车数量变更'); updateCartItems(); }); }); </script> <?php } add_action('wp_footer', 'track_cart_quantity_change_js');
额外说明
- 若购物车容器类名仍不匹配,可通过浏览器F12开发者工具查看实际DOM结构,替换
querySelector中的选择器 - 防抖时间可根据实际需求调整(当前为300ms)
- 若需要区分
addToCart和removeFromCart事件,可在对比状态时判断数量是增加还是减少,修改event字段值
内容的提问来源于stack exchange,提问作者Sergey Pervushin
相关产品推荐
相关产品推荐

