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

如何用JavaScript localStorage保存购物车修改,刷新后保留状态?

解决购物车修改无法持久化到localStorage及货币切换保存问题

购物车持久化失效的核心原因

  1. 初始HTML中的购物车项未添加cartItems类,导致saveCartToLocalStorage无法捕获这些项,第一次保存时localStorage为空数组
  2. 动态生成的删除按钮未绑定点击事件,无法触发删除逻辑
  3. 页面加载时未清空原有购物车项,导致localStorage数据与初始HTML项重复显示
  4. 数量输入框无默认值,保存时会存入空字符串,加载后显示异常

修复步骤及代码修改

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 01:15:58