Shopify Prestige主题侧边购物车无法自动刷新问题求助
问题背景
使用最新版Shopify Prestige主题搭建店铺,通过custom.js自定义购物车功能时,遇到添加商品后侧边购物车无法自动刷新的问题,必须手动硬刷新页面才能看到更新后的购物车内容。
相关代码片段
// Function to update the cart items inside the cart drawer function updateCartItems(cart) { const cartDrawer = document.querySelector('.cart-drawer'); if (!cartDrawer) return; const cartItems = cart.items || []; const cartItemsContainer = cartDrawer.querySelector('.cart-items-container'); // Clear the current cart items display cartItemsContainer.innerHTML = ''; // Loop through cart items and add them to the cart drawer cartItems.forEach(function (item) { const itemDiv = document.createElement('div'); itemDiv.textContent = item.title + ' x ' + item.quantity; cartItemsContainer.appendChild(itemDiv); }); } function onQuickBuyButtonClicked(id, pro_id) { const CartCount = document.getElementsByClassName('Header__CartCount')[0]; $(".loader_" + id).addClass("add-success--adding"); const product = { id: id, quantity: 1 }; $.ajax({ type: 'POST', url: '/cart/add.js', data: JSON.stringify(product), dataType: 'json', headers: { 'Content-Type': 'application/json' }, success: function (cart) { setTimeout(function () { $(".loader_" + id).removeClass("add-success--adding"); $(".loader_" + id).addClass("add-success--added"); // cartRecommended(pro_id); // Trigger the 'cart:refresh' event to update the cart count in the header document.dispatchEvent(new CustomEvent('cart:refresh', { bubbles: true, detail: { variant: cart } })); }, 500); // Update the cart items inside the cart drawer immediately updateCartItems(cart); setTimeout(function () { $(".loader_" + id).removeClass("add-success--adding").removeClass("add-success--added"); }, 1600); setTimeout(function () { // $('#backdrop').addClass('backdrop_active'); }, 2000); }, error: function (errorThrown) { $(".loader_" + id).removeClass("add-success--adding"); var r = jQuery.parseJSON(errorThrown.responseText); $(".error_" + pro_id).html("Error: " + r.description).show(); setTimeout(function () { $(".error_" + pro_id).html("").hide(100); }, 3000); } }); return false; } // Function to update the cart items when multiple items are added function updateCartOnItemAdded() { ShopifyAPI.getCart(function (cart) { updateCartItems(cart); }); } // Listen for the 'cart:refresh' event and update the cart items inside the cart drawer document.addEventListener('cart:refresh', function () { $.getJSON('/cart.js', function (cart) { const cartCount = cart.item_count || 0; const CartCount = document.getElementsByClassName('Header__CartCount')[0]; if (CartCount) { CartCount.innerHTML = cartCount; } // Update the cart items inside the cart drawer updateCartItems(cart); }); }); // Listen for the 'cart:item_added' event and update the cart items inside the cart drawer document.addEventListener('cart:item_added', function () { // Since the 'cart:refresh' event is not always triggered by all themes, // call the updateCartOnItemAdded function directly here to update the cart items updateCartOnItemAdded(); });
核心问题排查与解决方向
1. 购物车数据获取错误
Shopify的POST /cart/add.js接口返回的仅为刚添加的单个商品对象,并非完整的购物车数据(无items数组)。当前代码中直接用该响应对象调用updateCartItems,会导致cart.items为undefined,最终清空购物车显示但无法渲染正确内容。
修正方案:
在onQuickBuyButtonClicked的success回调中,替换直接使用响应对象的逻辑,改为请求完整购物车数据:
success: function (addedItem) { setTimeout(function () { $(".loader_" + id).removeClass("add-success--adding"); $(".loader_" + id).addClass("add-success--added"); document.dispatchEvent(new CustomEvent('cart:refresh', { bubbles: true, detail: { variant: addedItem } })); }, 500); // 替换原updateCartItems(cart),改为获取完整购物车数据 $.getJSON('/cart.js', function(fullCart) { updateCartItems(fullCart); }); // 其余原有逻辑... }
2. DOM元素存在性问题
Prestige主题的侧边购物车抽屉默认可能处于隐藏状态,甚至仅在用户点击购物车图标后才动态生成DOM元素。此时调用updateCartItems时,document.querySelector('.cart-drawer')会返回null,直接终止更新逻辑。
修正方案:
修改updateCartItems函数,增加抽屉元素不存在时的监听逻辑,等待抽屉打开后再执行更新:
function updateCartItems(cart) { const cartDrawer = document.querySelector('.cart-drawer'); if (!cartDrawer) { // 监听主题的购物车抽屉打开事件(Prestige主题通常触发'cart:opened'事件) const handleDrawerOpen = () => { updateCartItems(cart); document.removeEventListener('cart:opened', handleDrawerOpen); }; document.addEventListener('cart:opened', handleDrawerOpen); return; } // 原有渲染逻辑... }
3. 主题事件冲突或未触发
Prestige主题自身带有购物车更新逻辑,自定义的cart:refresh或cart:item_added事件可能未被主题正确触发,或者与主题自带事件冲突。
验证与修正:
- 直接在商品添加成功后强制调用更新逻辑,不依赖事件监听:在
onQuickBuyButtonClicked的success回调中添加updateCartOnItemAdded(); - 检查主题官方文档,确认其自带的购物车相关事件名称,替换自定义事件监听。
4. 异步逻辑顺序问题
当前代码中存在多个setTimeout,可能导致事件触发与DOM更新的顺序混乱,例如cart:refresh事件触发时,购物车抽屉的DOM还未准备完成。
修正方案:
调整setTimeout的顺序,确保所有更新逻辑在DOM状态稳定后执行,或者移除不必要的延迟,优先完成购物车数据更新。
内容的提问来源于stack exchange,提问作者user19889863

