如何利用localStorage实现页面刷新后保持按钮禁用状态
问题核心
你当前的代码存在两个关键问题:
- 用全局的
disabled字段存到localStorage,无法区分多个商品的禁用状态,且页面刷新后没有基于实际商品库存数据初始化按钮状态 - 页面加载时本地
products数组还是默认的inCart:0,没有同步localStorage里已更新的商品数据,导致按钮状态判断错误
修复方案
1. 新增页面加载时的商品状态同步函数
这个函数会读取localStorage里的购物车数据,同步到本地products数组,并根据库存初始化按钮禁用状态:
function loadProductState() { let cartItems = localStorage.getItem("productsInCart"); if (cartItems) { cartItems = JSON.parse(cartItems); // 同步localStorage商品数据到本地数组 for (let id in cartItems) { const product = products.find(p => p.id == id); if (product) { product.inCart = cartItems[id].inCart; } } // 遍历按钮设置禁用状态 euro.forEach((btn, index) => { btn.disabled = products[index].inCart >= products[index].lager; }); } }
2. 修改按钮点击事件的禁用逻辑
不需要单独存储disabled状态,直接基于商品的inCart和库存判断:
for (let i = 0; i < euro.length; i++) { euro[i].addEventListener("click", () => { cartNumbers(products[i]); totalCost(products[i]); // 点击后立即检查库存,禁用按钮 if (products[i].inCart >= products[i].lager) { euro[i].disabled = true; } }); }
3. 优化setItems函数(确保数据同步)
修正商品inCart值的同步逻辑,避免本地和localStorage数据不一致:
function setItems(product) { let cartItems = localStorage.getItem("productsInCart"); cartItems = JSON.parse(cartItems); if (cartItems != null) { if (cartItems[product.id] == undefined) { cartItems = { ...cartItems, [product.id]: {...product, inCart: 1} }; product.inCart = 1; } else { cartItems[product.id].inCart += 1; product.inCart = cartItems[product.id].inCart; } } else { product.inCart = 1; cartItems = { [product.id]: {...product} }; } localStorage.setItem("productsInCart", JSON.stringify(cartItems)); }
4. 页面初始化时调用新函数
在现有初始化代码后,添加状态同步函数的调用:
onLoadCartNumbers(); loadProductState();
完整修改后的代码
let cartNr = document.getElementById("cartNr"); const lang1 = document.querySelector(".lang1"); cartNr = 1; let products = [ { id: 0, namn: "Sneaker1", img: "//shelta.se/pub_images/original/DV1129-300_1.jpg?timestamp=1677759773", pris: 1500, lager: 10, inCart: 0, }, { id: 1, namn: "Sneaker2", img: "https://shelta.se/pub_images/original/AH6789-006_1.jpg", pris: 1500, lager: 10, inCart: 0, }, { id: 2, namn: "Sneaker3", img: "https://shelta.se/pub_images/original/DV1129-001_1.jpg?timestamp=1673044814", pris: 1500, lager: 10, inCart: 0, }, { id: 3, namn: "Sneaker4", img: "https://shelta.se/pub_images/original/AH6789-001_1.jpg?timestamp=1609192138", pris: 1500, lager: 10, inCart: 0, }, { id: 4, namn: "Sneaker5", img: "https://shelta.se/pub_images/original/DM2361-100_0.jpg?timestamp=1628091117", pris: 1500, lager: 10, inCart: 0, }, ]; const euro = document.querySelectorAll(".euro"); for (let i = 0; i < euro.length; i++) { euro[i].addEventListener("click", () => { cartNumbers(products[i]); totalCost(products[i]); // 点击后检查库存并禁用按钮 if (products[i].inCart >= products[i].lager) { euro[i].disabled = true; } }); } function onLoadCartNumbers() { let productNumbers = localStorage.getItem("cartNumbers"); if (productNumbers) { lang1.innerHTML = `<div id="cartNr">${(cartNr = productNumbers)}</div>`; } } function loadProductState() { let cartItems = localStorage.getItem("productsInCart"); if (cartItems) { cartItems = JSON.parse(cartItems); // 同步localStorage数据到本地数组 for (let id in cartItems) { const product = products.find(p => p.id == id); if (product) { product.inCart = cartItems[id].inCart; } } // 初始化按钮禁用状态 euro.forEach((btn, index) => { btn.disabled = products[index].inCart >= products[index].lager; }); } } function cartNumbers(product) { console.log("the product clicked is", product); let productNumbers = localStorage.getItem("cartNumbers"); productNumbers = parseInt(productNumbers); if (productNumbers) { localStorage.setItem("cartNumbers", productNumbers + 1); lang1.innerHTML = `<div id="cartNr">${(cartNr = productNumbers + 1)}</div>`; } else { localStorage.setItem("cartNumbers", 1); lang1.innerHTML = `<div id="cartNr">${(cartNr = 1)}</div>`; } setItems(product); } function setItems(product) { let cartItems = localStorage.getItem("productsInCart"); cartItems = JSON.parse(cartItems); if (cartItems != null) { if (cartItems[product.id] == undefined) { cartItems = { ...cartItems, [product.id]: {...product, inCart: 1} }; product.inCart = 1; } else { cartItems[product.id].inCart += 1; product.inCart = cartItems[product.id].inCart; } } else { product.inCart = 1; cartItems = { [product.id]: {...product} }; } localStorage.setItem("productsInCart", JSON.stringify(cartItems)); } function totalCost(product) { let cartCost = localStorage.getItem("totalCost"); if (cartCost != null) { cartCost = parseInt(cartCost); localStorage.setItem("totalCost", cartCost + product.pris); } else { localStorage.setItem("totalCost", product.pris); } } async function patchPost(obj) { const baseURL = `https://webstore-22fa4-default-rtdb.europe-west1.firebasedatabase.app/`; const url = baseURL + `Products.json`; const init = { method: "PUT", body: JSON.stringify(obj), headers: { "Content-type": "application/json; charset=UTF-8", }, }; const response = await fetch(url, init); const data = await response.json(); console.log(data); } let obj = Object.values(products); patchPost(obj); console.log(obj); onLoadCartNumbers(); loadProductState();
关键说明
loadProductState函数会在页面加载时同步localStorage的商品数据,并自动设置按钮的禁用状态- 不再单独存储
disabled状态,直接基于商品的inCart和lager值判断,避免状态不一致 - 优化后的
setItems函数确保本地数组和localStorage的数据完全同步
内容的提问来源于stack exchange,提问作者gritoverflow
相关产品推荐
相关产品推荐

