有没有一种方法可以将图像和字符串添加到数组并存储在本地存储中并使用 JavaScript 显示它们?

is there a way I can add images and strings to an array and store on local storage and display them using JavaScript?

我正在构建一个食谱应用程序,该应用程序显示食物图像及其各自的名称,来自 spoonicular api。因此,当用户看到他们喜欢的食物时,他们会点击喜欢的图标,这反过来会将食物添加到顶部的最喜欢的部分。其逻辑是图片 url 和食物的名称将存储在本地存储中,然后显示在收藏部分。但是我有以下问题 1.i 尽管已成功将图像和名称存储在本地存储中,但似乎无法显示它们 2.The 点赞图标,点击后激活仅对第一个食物有效 下面是我的代码

  document.getElementById("search").addEventListener("click",()=>{
const input=document.getElementById("input")
input.style.display="block"
input.style.border="solid"
})

 let myFavMeals=[]
function getRandomMeal(){
fetch('https://api.spoonacular.com/recipes/random?number=10&apiKey=b354ffb530c5444da1eec4b02a3146be').then((data)=>{
  console.log(data)
  return data.json()
}).then((completedata)=>{
console.log(completedata.recipes)
  let data1=""
  completedata.recipes.forEach((recipe) => {
    const {
      id,
      title,
      readyInMinutes,
      servings,
      image,
      dishTypes,
      instructions,
    } = recipe;
    console.log(recipe)
      data1+=`  
      <div class="meal-header">
          <img src=${recipe.image} alt=${recipe.title} >
      </div>
      <div class="meal-body">
          <h5>${recipe.title}</h5>
          <button class="fav-btn">
              <i class="fa fa-heart"></i>
          </button>
      </div>`
      const meal=document.querySelector(".meal")
      meal.innerHTML=data1
      const favBtn=meal.querySelector(".fav-btn i")
      favBtn.addEventListener("click",()=>{
          favBtn.classList.add("active")
          let array1=[recipe.image,recipe.title]
          myFavMeals.push(...array1)
          console.log(myFavMeals)
          localStorage.setItem("myFavMeals",JSON.stringify(myFavMeals))
         showMeal()
      })
})

 }).catch((err)=>{
  console.log(err)
 })
  }
getRandomMeal()


   function getMealBySearch(){
  document.querySelector('#input').addEventListener('keypress', function (e) {
if (e.key === 'Enter') { 
  const term=document.getElementById("input").value
  fetch(`https://api.spoonacular.com/recipes/complexSearch? 
  query=${term}&number=10&apiKey=b354ffb530c5444da1eec4b02a3146be`).then((data)=>{
    console.log(data) 
  return data.json()
    
}).then((completedata)=>{
  console.log(completedata)
  console.log(completedata.results)
let data3=""
completedata.results.forEach((recipe) => {
  const {
    id,
    title,
    readyInMinutes,
    servings,
    image,
    dishTypes,
    instructions,
  } = recipe;
    data3+=`
    <div class="meal-header">
        <img src=${recipe.image} alt=${recipe.title}>
    </div>
    <div class="meal-body">
        <h5>${recipe.title}</h5>
        <button class="fav-btn">
            <i class="fa fa-heart"></i>
        </button>
    </div>`
      
    const favBtn=document.querySelector(".fav-btn i")
    favBtn.addEventListener("click",()=>{
        favBtn.classList.toggle("active")
        let array1=[recipe.image,recipe.title]
        myFavMeals.push(...array1)
        console.log(myFavMeals)
        localStorage.setItem("myFavMeals",JSON.stringify(myFavMeals))
       showMeal()
 
    
   })
     
})
const meal=document.querySelector(".meal")
      meal.innerHTML=data3
     

}).catch((err)=>{
  console.log(err)
  })
   }
  });

 }
 getMealBySearch()
 

    function showMeal(){
       let favmeal= JSON.parse(localStorage.getItem(myFavMeals)) 
        renderFavMeal()
      
        function renderFavMeal(){
          meallist=""
          favmeal.forEach((meal) => {
            const {
              image,
              name
            } = meal;
              meallist+=`<ul>
              <li><img src=${meal.image} alt=${meal.name}><span>${meal.name}</span></li>
          </ul>`
          })
          document.querySelector(".fav-meals").innerHTML=meallist
        }
      }
  
    
      

retrieving data from local storage 您需要使用您保存的密钥 (DOMstring) 时。

let favmeal = JSON.parse(localStorage.getItem(myFavMeals))

通过这种方式,您可以尝试检索您在上面的代码中设置的数组。将其放在引号中以使其成为密钥:

let favmeal = JSON.parse(localStorage.getItem("myFavMeals"))

你应该针对这些问题提出单独的问题。但是图标变为活动状态,因为您只选择了第一个。

const favBtn = meal.querySelector(".fav-btn i")

此选择器仅选择与查询匹配的第一个元素。

Insead 你应该使用 querySelectorAll() 并循环遍历节点列表

const favBtns = meal.querySelectorAll(".fav-btn i")
const images = document.querySelectorAll('.meal-header > img')

favBtns.forEach((favBtn, i) => {
      favBtn.addEventListener("click", () => {
          favBtn.classList.add("active")      
          myFavMeals.push(images[i].src, images[i].alt)
          localStorage.setItem("myFavMeals", JSON.stringify(myFavMeals))
          showMeal()
          })
    })

您还应该将其从您现在所在的循环中删除。现在您正在为每个循环添加相同的侦听器。

您想 运行 创建您的 html 的循环。插入到想要的元素中。然后循环遍历喜欢的按钮并为每个按钮添加事件侦听器。

因此,在 getRandomMeal 函数中,您也希望将这段代码置于循环之外。所以你不必在每个循环中插入数据。

  const meal = document.querySelector(".meal")
  meal.innerHTML = data1