修复商品按钮库存耗尽仍可点击问题:实现单按钮禁用逻辑
电商购物车按钮禁用问题修复
问题描述
开发电商店铺页面时,商品库存(lager)设为10,需求是:点击商品的「添加至购物车」按钮时,当该商品的购物车数量(inCart)达到库存上限10,仅禁用该商品对应的按钮,其他商品按钮仍可正常使用。但当前代码存在问题:即使某商品的inCart超过10,其按钮仍能继续被点击,无法自动禁用。
原代码
let cartNr = document.getElementById('cartNr') const lang1 = document.querySelector('.lang1') cartNr = 1 let products = [ { id: 0, namn: 'Sneaker1', img: 0, pris: 1500, lager: 10, inCart: 0 }, { id: 1, namn: 'Sneaker2', img: 1, pris: 1500, lager: 10, inCart: 0 }, { id: 2, namn: 'Sneaker3', img: 2, pris: 1500, lager: 10, inCart: 0 }, { id: 3, namn: 'Sneaker4', img: 3, pris: 1500, lager: 10, inCart: 0 }, { id: 4, namn: 'Sneaker5', img: 4, 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 >= 10){ euro[i].disabled = true } }) } function onLoadCartNumbers(){ let productNumbers = localStorage.getItem('cartNumbers') if(productNumbers){ lang1.innerHTML = `<div id="cartNr">${cartNr = productNumbers}</div>` } } 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) console.log(cartItems) //funkar if(cartItems != null){ if(cartItems[product.img] == undefined){ cartItems = { ...cartItems, [product.img]: product } console.log(cartItems) }else { cartItems[product.img].inCart += 1 console.log(cartItems) //funkar } } else{ product.inCart = 1 cartItems = { [product.img]: product } console.log(cartItems)//funkar } localStorage.setItem('productsInCart',JSON.stringify(cartItems)) console.log(localStorage.getItem('productsInCart')) } 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()
问题原因
- 数据同步不一致:点击事件中调用
cartNumbers后,setItems函数修改的是从localStorage取出的对象,而非原始products数组中的元素,导致判断inCart >=10时使用的是旧值,无法触发禁用逻辑。 - 初始化未同步状态:页面加载时未从localStorage读取购物车数据,同步更新
products数组和对应按钮的禁用状态,刷新页面后按钮状态不会恢复。
修复方案
1. 修正点击事件的判断逻辑
点击按钮后,从localStorage读取最新购物车数据同步到products数组,再判断是否禁用按钮:
for(let i = 0; i < euro.length; i++ ){ euro[i].addEventListener('click', () => { cartNumbers(products[i]) totalCost(products[i]) // 同步最新购物车数据到products数组 let cartItems = JSON.parse(localStorage.getItem('productsInCart')) if(cartItems && cartItems[products[i].img]){ products[i].inCart = cartItems[products[i].img].inCart } // 根据库存上限判断是否禁用按钮 if(products[i].inCart >= products[i].lager){ euro[i].disabled = true } }) }
2. 页面初始化时同步按钮状态
修改onLoadCartNumbers函数,页面加载时同步购物车数据并更新按钮状态:
function onLoadCartNumbers(){ let productNumbers = localStorage.getItem('cartNumbers') if(productNumbers){ lang1.innerHTML = `<div id="cartNr">${cartNr = productNumbers}</div>` } // 同步购物车数据到products数组,更新按钮禁用状态 let cartItems = JSON.parse(localStorage.getItem('productsInCart')) if(cartItems){ Object.values(cartItems).forEach(item => { const product = products.find(p => p.img === item.img) if(product){ product.inCart = item.inCart const btn = euro[product.id] if(btn && product.inCart >= product.lager){ btn.disabled = true } } }) } }
3. 优化setItems函数(可选)
确保setItems修改inCart时同步更新原始products数组,避免数据不一致:
function setItems(product){ let cartItems = localStorage.getItem('productsInCart') cartItems = JSON.parse(cartItems) if(cartItems != null){ if(cartItems[product.img] == undefined){ cartItems = { ...cartItems, [product.img]: product } product.inCart = 1 } else { cartItems[product.img].inCart += 1 // 同步更新products数组中的对应元素 const targetProduct = products.find(p => p.img === product.img) if(targetProduct){ targetProduct.inCart = cartItems[product.img].inCart } } } else { product.inCart = 1 cartItems = { [product.img]: product } } localStorage.setItem('productsInCart',JSON.stringify(cartItems)) }
内容的提问来源于stack exchange,提问作者gritoverflow
相关产品推荐
相关产品推荐

