LocalStorage不断恢复删除的值



我正在使用本地存储API将物品存储在购物车中,但我遇到了问题。起初,当我将物品添加到购物车中时,它正常工作,当我移除物品时,它也正常工作。但是,当我尝试将一个项目添加到购物车时,localStorage会带回所有删除的项目。

下面有两个功能,

  • AddToCart()–从主页和单个产品页面添加项目
  • removeFromCart()–从购物车中移除物品
function AddToCart(){
// Home page 
var data = JSON.parse(localStorage.getItem('zysod_cart'))
$('.addcart').on('click', function(){
var $this = $(this).closest('.single-product-content')
var productId = parseInt($this.attr('data-product-id'))
var productName = $this.find('.product-title').text()
var productImg = $this.attr('data-product-src')
var productPrice = $this.find('.product-price .regular-price').text()
var found = data.products.some(function(el){
return parseInt(el.id) === productId
})
if (!found) {
data.items = parseInt(data.items) + 1;          
data.products.push({
id: productId,
name: productName,
quantity: 1,
image: productImg,
price: productPrice
});
var total = 0
for(var item in data.products){
total += (data.products[item].price === 'Price not available'? 0 : parseInt(data.products[item].price.replace(',','').slice(1))) * data.products[item].quantity
}
data.total = total
localStorage.setItem('zysod_cart', JSON.stringify(data));
UpdateCart()
} else {
for (var i = 0; i < data.products.length; i++) {
if (parseInt(data.products[i].id) === productId) {
data.products[i].quantity = parseInt(data.products[i].quantity + 1);
var total =0;
for(var item in data.products){
total += (data.products[item].price === 'Price not available'? 0 : parseInt(data.products[item].price.replace(',','').slice(1))) * data.products[item].quantity
}
data.total = total              
localStorage.setItem('zysod_cart', JSON.stringify(data));
UpdateCart()
}
}
}
})
// Single Product Page
$('.h-addcart').on('click',function(){
var $this = $(this).closest('.single-product')
var productId = parseInt($this.attr('data-product-id'))
var productName = $this.find('.product-title').text()
var productImg = $this.attr('data-product-src')
var productPrice = $this.find('.product-price .price-sale').text()
var found = data.products.some(function(el){
return parseInt(el.id) === productId
})
if (!found) {

data.items = parseInt(data.items) + 1;          
data.products.push({
id: productId,
name: productName,
quantity: 1,
image: productImg,
price: productPrice              
});
var total =0;
for(var item in data.products){
total += (data.products[item].price === 'Price not available'? 0 : parseInt(data.products[item].price.replace(',','').slice(1))) * data.products[item].quantity
}
data.total = total          
localStorage.setItem('zysod_cart', JSON.stringify(data));

} else {
for (var i = 0; i < data.products.length; i++) {
if (parseInt(data.products[i].id) === productId) {
data.products[i].quantity = parseInt(data.products[i].quantity + 1);
var total =0;
for(var item in data.products){
total += (data.products[item].price === 'Price not available'? 0 : parseInt(data.products[item].price.replace(',','').slice(1))) * data.products[item].quantity
}
data.total = total              
localStorage.setItem('zysod_cart', JSON.stringify(data));

}
}
}
})
}
function removeFromCart(){
$(document).on('click','.dropcart__product-remove',function(){        
var $this = $(this).closest('.dropcart__product')
var productId = parseInt($this.attr('data-product-id'))
var data = JSON.parse(localStorage.getItem('zysod_cart'));        
data.products = $.grep(data.products, function (e) {
if(e.id == productId){
data.total-= e.price === 'Price not available'? parseInt(0): (parseInt(e.price.replace(',','').slice(1))*parseInt(e.quantity))
}
return e.id != productId;
}); 
data.items = data.products.length
localStorage.setItem('zysod_cart', JSON.stringify(data));          

})
}

这是因为data在调用AddToCart时读取一次。

function AddToCart() {
var data = JSON.parse(localStorage.getItem('zysod_cart'))
// ...
}

ℹ️这是因为闭包引用了上层作用域中最顶层的data变量。阅读Mozilla开发者网络文章中关于闭包的更多信息。

如果要解决此问题,每次更改数据时都应该从localStorage读取data,就像在每个click事件处理程序中的removeFromCart()中所做的那样:

function removeFromCart(){
$(document).on('click','.dropcart__product-remove',function(){        
var $this = $(this).closest('.dropcart__product')
var productId = parseInt($this.attr('data-product-id'))
var data = JSON.parse(localStorage.getItem('zysod_cart')); 
// ...
})
}

⚠️需要注意的是,几个选项卡可以同时更新localStorage,这可能会导致冲突。为了避免这种情况,建议使用SharedWorker来同步不同的选项卡。

建议

如果需要的话,我建议让你的代码模块化并可支持。您可以将事件处理和本地存储操作分开,如下所示:

class Storage {
constructor(name, data) {
this.name = name
if (data) {
this.save(data)
} else {
if (name in localStorage) {
this.data = JSON.parse(localStorage.getItem(name))
} else {
this.save({})
}
}
}

save(data) {
this.data = data
this.updateStorage()
}
updateStorage() {
localStorage.setItem(this.name, JSON.stringify(this.data))
}
}
const storage = new Storage('zysod_cart')
function bindAddToCart(storage) {
$('#addButton').on('click', function () {
// Copy data
const data = {...storage.data}

// Add cart logic here ...
// Save changes
storage.save(data)
})
}
function bindRemoveFromCard(storage) {
$('#removeButton').on('click', function () {
// Copy data
const data = {...storage.data}
// Remove card logic here ...
// Save changes
storage.save(data)
})
}

但请注意,页面上应该只有一个Storagename值为zysod_cart的实例。

最新更新