问题描述
我需要做的是当我点击 heartBtn
时它会变成红色并将该项目添加到 localstorage productsInFavArr
中的一组对象中,当我再次点击它时它应该会变成灰色并删除来自 productsInFavArr
的对象。
添加功能完美地将项目添加到 arr 部分,但 drawProductUI
函数应该检查产品是否存在于 productsInFacArr
中,btn 将是红色的,如果不是,它会是灰色的,所以我在添加和删除项目后将 drawProductUI
函数放在添加和删除函数中,但它在我重新加载页面之前不起作用
并且删除函数在两次点击后从 arr 中删除对象,但仍然没有改变 btn 的 colot
所以我的主要问题是在添加或删除项目后更改 btn 的颜色,并且删除功能在两次点击后删除项目
代码如下:
// Draw Product UI
function drawProductUI(array){
var productsUI = array.map((item) => {
if (productsInFavArr) {
for (const favProd of productsInFavArr){
if (favProd.id === item.id) {
// console.log(favProd);
return `
<div class="product-item">
<div class="product-img-container">
<img src=${item.imgurL} alt="products" class="product-img" width="100%" height="150px">
</div>
<div class="product-text">
<h2 class="product-title">${item.title}</h2>
<span class="product-desc">${item.desc}</span>
<p class="product-price">USD ${item.price}</p>
</div>
<div class="product-btns">
<button class="add-to-cart">Add To Cart</button>
<button class="heart-btn heart-icon-red" onclick="removeItemFromFav( ${item.id} )"><i class="far fa-heart"></i></button>
</div>
</div>
`;
}
}}
return`
<div class="product-item">
<div class="product-img-container">
<img src=${item.imgurL} alt="products" class="product-img" width="100%" height="150px">
</div>
<div class="product-text">
<h2 class="product-title">${item.title}</h2>
<span class="product-desc">${item.desc}</span>
<p class="product-price">USD ${item.price}</p>
</div>
<div class="product-btns">
<button class="add-to-cart">Add To Cart</button>
<button class="heart-btn heart-icon" ><i class="far fa-heart"></i></button>
</div>
</div>
`
});
productsContainer.innerHTML = productsUI.join("");
}
drawProductUI(allProducts)
// add to favorites
for(let f=0; f < heartBtn.length; f++){
heartBtn[f].addEventListener("click",()=>{
addToFavorites(allProducts[f]);
function addToFavorites(product){
if (localStorage.getItem("userValidate") && localStorage.getItem("passValidate")) {
let productsInFavObj = localStorage.getItem("productsInFavObj");
productsInFavObj = JSON.parse(productsInFavObj);
if(productsInFavObj != null){
if(productsInFavObj[product.id] == undefined){
productsInFavObj = {
...productsInFavObj,[product.id] : product
}
}
}else{
productsInFavObj = {
[product.id] : product
}
}
let productsInFavArr = Object.values(productsInFavObj)
localStorage.setItem("productsInFavArr",JSON.stringify(productsInFavArr) )
localStorage.setItem("productsInFavObj",JSON.stringify(productsInFavObj) )
}else{
window.location.href = "login.html";
}
}
drawProductUI(allProducts)
})
}
// Remove From Favorite
function removeItemFromFav(id){
for(let f=0; f < heartBtn.length; f++){
let productsInFavArr = localStorage.getItem("productsInFavArr")
if(productsInFavArr){
let items = JSON.parse(productsInFavArr);
console.log("removed item:",allProducts[f]);
let filteredItems = items.filter((item) => item.id !== id);
localStorage.setItem("productsInFavArr",JSON.stringify(filteredItems));
localStorage.setItem("productsInFavObj",JSON.stringify(filteredItems) )
drawProductUI(allProducts)
console.log(filteredItems);
if(filteredItems.length==0){
localStorage.removeItem("productsInFavArr")
localStorage.removeItem("productsInFavObj")
}
}
}
}
这里是产品示例
let products = [
{
title: "Sunglasses",imgurL: "images/Products/sunglasses.jpg",desc: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut nulla adipisci fugiat pariatur recusandae repudiandae fuga molestias doloremque itaque obcaecati.",price:80,id: 1
},{
title: "Laptop",imgurL: "images/Products/laptop.jpg",price:100,id: 2
},{
title: "Microphone",imgurL: "images/Products/mic.jpg",price:75,id: 3
},{
title: "Cat",imgurL: "images/Products/cat.jpg",price:200,id: 4
},]
谢谢
解决方法
在 drawProductUI
函数中,您不是读取本地存储值,而是取决于 productsInFavArr
,它可能只读取本地存储值一次。我认为您需要在调用 drawProductUI 时获取新值,以便在不重新加载页面的情况下反映对本地存储所做的更改。
function drawProductUI(array){
let productsInFavArr = JSON.parse(localStorage.getItem("productsInFavArr")) || []; // read the value here so it's fresh before redraw happens
var productsUI = array.map((item) => {
// rest of the function code
在 drawProductUI
函数中,您为所选项目定义处理程序:
<button class="heart-btn heart-icon-red" onclick="removeItemFromFav(${item.id})">
<i class="far fa-heart"></i>
</button>
您应该对未选择的按钮版本执行相同操作:
<button class="heart-btn heart-icon" onclick="addToFavorites(${item.id})">
<i class="far fa-heart"></i>
</button>
这样,每次重绘 UI 时都会附加点击处理程序,而不仅仅是在读取 js 文件时附加一次,这是您当前定义处理程序时的情况。
有了这个,你需要在顶层定义 addToFavorites
函数,所以在循环之外,就像你定义 removeItemFromFav
一样。
由于处理程序现在获取产品的 id,因此您需要在处理之前找到合适的产品。
您还想在单击时重绘 UI,因此将适当的方法添加到函数底部。
我附上了说明这些变化的评论:
function addToFavorites(id){ // this is now defined at the top level as removeItemFromFav
if (localStorage.getItem("userValidate") && localStorage.getItem("passValidate")) {
const product = allProducts.find(p => p.id == id); // this and next lines handle product lookup
if (!product) { return; }
let productsInFavObj = localStorage.getItem("productsInFavObj");
productsInFavObj = JSON.parse(productsInFavObj);
if(productsInFavObj != null){
if(productsInFavObj[id] == undefined){
productsInFavObj = {
...productsInFavObj,[id] : product
}
}
}else{
productsInFavObj = {
[id] : product
}
}
let productsInFavArr = Object.values(productsInFavObj)
localStorage.setItem("productsInFavArr",JSON.stringify(productsInFavArr) )
localStorage.setItem("productsInFavObj",JSON.stringify(productsInFavObj) )
drawProductUI(allProducts); // this redraws the UI
}else{
window.location.href = "login.html";
}
}
最后要更正的是 removeItemFromFav
函数。
不需要循环
function removeItemFromFav(id){
// loop is gone now,also console.logs are gone
let productsInFavArr = localStorage.getItem("productsInFavArr")
if(productsInFavArr){
let items = JSON.parse(productsInFavArr);
let filteredItems = items.filter((item) => item.id !== id);
localStorage.setItem("productsInFavArr",JSON.stringify(filteredItems));
localStorage.setItem("productsInFavObj",JSON.stringify(filteredItems) )
drawProductUI(allProducts)
if(filteredItems.length==0){
localStorage.removeItem("productsInFavArr")
localStorage.removeItem("productsInFavObj")
}
}
}