如何用JavaScript localStorage保存购物车修改,刷新后保留状态?
解决购物车修改无法持久化到localStorage及货币切换保存问题
购物车持久化失效的核心原因
- 初始HTML中的购物车项未添加
cartItems类,导致saveCartToLocalStorage无法捕获这些项,第一次保存时localStorage为空数组 - 动态生成的删除按钮未绑定点击事件,无法触发删除逻辑
- 页面加载时未清空原有购物车项,导致localStorage数据与初始HTML项重复显示
- 数量输入框无默认值,保存时会存入空字符串,加载后显示异常
修复步骤及代码修改
1. 修正HTML结构
给初始购物车项的<tr>添加cartItems类,同时给数量输入框设置默认值value="1":
<!-- 1st section cart items --> <div class="table_container"> <table> <tr> <th></th> <th>Product</th> <th>Price</th> <th>Qauntity</th> <th>Remove</th> </tr> <div class="product_items"> <!-- first item --> <tr class="cartItems"> <td><img src="./assets/images/tutu-skirt1.jpg" alt="" class="shop-item-image"></td> <td><h2 class="shop-item-title">tutu Skirt</h2></td> <td><p class="shop-item-price">5 JOD</p></td> <td><input type="number" name="Qauntity" id="qauntity" value="1"></td> <td><span class="material-symbols-outlined delete_icon">delete</span></td> </tr> <!-- other item --> <tr class="cartItems"> <td><img src="./assets/images/tutu-skirt2.jpg" alt="" class="shop-item-image"></td> <td><h2 class="shop-item-title">tutu Skirt</h2></td> <td><p class="shop-item-price">5 JOD</p></td> <td><input type="number" name="Qauntity" id="qauntity" value="1"></td> <td><span class="material-symbols-outlined delete_icon">delete</span></td> </tr> <!-- other item --> <tr class="cartItems"> <td><img src="./assets/images/tutu-skirt3.jpg" alt="" class="shop-item-image"></td> <td><h2 class="shop-item-title">tutu Skirt</h2></td> <td><p class="shop-item-price">5 JOD</p></td> <td><input type="number" name="Qauntity" id="qauntity" value="1"></td> <td><span class="material-symbols-outlined delete_icon">delete</span></td> </tr> </div> </table> </div> <div class="total"> <p>Total Price : <strong class="cart-total-price">15.00 JOD</strong></p> <button class="btn buy">Purchase</button> </div>
2. 重构JavaScript逻辑
使用事件委托处理删除和数量变化,修复localStorage读写逻辑,添加总价更新:
// 事件委托:处理删除按钮点击(兼容动态生成的按钮) document.querySelector('.product_items').addEventListener('click', function(event) { if (event.target.classList.contains('delete_icon')) { deleteItemFromCart(event); } }); // 事件委托:处理数量变化 document.querySelector('.product_items').addEventListener('change', function(event) { if (event.target.name === 'Qauntity') { saveCartToLocalStorage(); updateCartTotal(); } }); // 页面加载时加载购物车和货币设置 window.addEventListener("load", function() { loadCartFromLocalStorage(); loadCurrencySetting(); }); function deleteItemFromCart(event) { var deleteBtn = event.target; var cartItem = deleteBtn.parentNode.parentNode; cartItem.remove(); saveCartToLocalStorage(); updateCartTotal(); } function saveCartToLocalStorage() { var cartItems = document.getElementsByClassName("cartItems"); var cartItemsData = []; for (var i = 0; i < cartItems.length; i++) { var cartItem = cartItems[i]; var image = cartItem.querySelector(".shop-item-image").src; var title = cartItem.querySelector(".shop-item-title").textContent; var price = cartItem.querySelector(".shop-item-price").textContent; var quantity = cartItem.querySelector("input[name='Qauntity']").value || 1; var itemData = { image: image, title: title, price: price, quantity: quantity }; cartItemsData.push(itemData); } localStorage.setItem("cartItems", JSON.stringify(cartItemsData)); } function loadCartFromLocalStorage() { var cartItemsData = localStorage.getItem("cartItems"); var productItemsContainer = document.querySelector(".product_items"); // 清空原有内容,避免重复加载 productItemsContainer.innerHTML = ''; if (cartItemsData) { var cartItemsArray = JSON.parse(cartItemsData); for (var i = 0; i < cartItemsArray.length; i++) { var itemData = cartItemsArray[i]; var cartItem = document.createElement("tr"); cartItem.classList.add("cartItems"); cartItem.innerHTML = ` <td><img src="${itemData.image}" alt="" class="shop-item-image"></td> <td><h2 class="shop-item-title">${itemData.title}</h2></td> <td><p class="shop-item-price">${itemData.price}</p></td> <td><input type="number" name="Qauntity" value="${itemData.quantity || 1}"></td> <td><span class="material-symbols-outlined delete_icon"> delete </span></td> `; productItemsContainer.appendChild(cartItem); } updateCartTotal(); } else { // 首次加载时保存初始购物车项 saveCartToLocalStorage(); } } // 更新购物车总价 function updateCartTotal() { var cartItems = document.getElementsByClassName("cartItems"); var total = 0; for (var i = 0; i < cartItems.length; i++) { var cartItem = cartItems[i]; var priceElement = cartItem.querySelector(".shop-item-price"); var quantityElement = cartItem.querySelector("input[name='Qauntity']"); // 提取价格数值 var price = parseFloat(priceElement.textContent.replace(/[^\d.]/g, '')) || 0; var quantity = parseInt(quantityElement.value) || 0; total += price * quantity; } total = Math.round(total * 100) / 100; var currency = localStorage.getItem('selectedCurrency') || 'JOD'; document.querySelector(".cart-total-price").textContent = total.toFixed(2) + ' ' + currency; localStorage.setItem('cartTotal', total.toFixed(2) + ' ' + currency); } // 货币切换持久化逻辑 function saveCurrencySetting(currency) { localStorage.setItem('selectedCurrency', currency); updateCartPrices(currency); saveCartToLocalStorage(); } function loadCurrencySetting() { var selectedCurrency = localStorage.getItem('selectedCurrency') || 'JOD'; updateCartPrices(selectedCurrency); } // 根据货币类型更新商品价格(示例汇率,需根据实际需求调整) function updateCartPrices(currency) { var priceElements = document.querySelectorAll('.shop-item-price'); // 假设原始价格为5 JOD const basePrice = 5; let exchangeRate = 1; let currencySymbol = 'JOD'; switch(currency) { case 'USD': exchangeRate = 1.41; currencySymbol = 'USD'; break; case 'EUR': exchangeRate = 1.32; currencySymbol = 'EUR'; break; default: exchangeRate = 1; currencySymbol = 'JOD'; } priceElements.forEach(el => { const convertedPrice = (basePrice * exchangeRate).toFixed(2); el.textContent = `${convertedPrice} ${currencySymbol}`; }); updateCartTotal(); }
货币切换功能使用示例
当用户切换货币时,调用saveCurrencySetting函数即可保存设置:
// 示例:绑定货币切换按钮 document.getElementById('usd-btn').addEventListener('click', () => saveCurrencySetting('USD')); document.getElementById('eur-btn').addEventListener('click', () => saveCurrencySetting('EUR')); document.getElementById('jod-btn').addEventListener('click', () => saveCurrencySetting('JOD'));
内容的提问来源于stack exchange,提问作者Sarah Bader
相关产品推荐
相关产品推荐

