如何在模式中插入保存到收藏夹功能 link?

How to insert save to favourites feature link within modal?

我正在使用显示图像的 NASA API,当单击图像时,它会显示一个包含图像和图像细节的模式。

但是,在教程中,有一个保存到收藏夹的功能,可以将图像和细节添加到收藏夹部分到本地存储。

我的问题是,如何将添加到收藏夹功能 link 实现到模式中,然后将图像和详细信息保存到本地存储收藏夹部分?

const resultsNav = document.getElementById("resultsNav");
const favoritesNav = document.getElementById("favoritesNav");
const imagesContainer = document.querySelector(".images-container");
const saveConfirmed = document.querySelector(".save-confirmed");
const loader = document.querySelector(".loader");

// NASA API
const count = 3;
const apiKey = 'DEMO_KEY';
const apiUrl = `https://api.nasa.gov/planetary/apod?api_key=${apiKey}&count=${count}`;

let resultsArray = [];
let favorites = {};

// Show Content
function showContent(page) {
  window.scrollTo({
    top: 0,
    behavior: "instant"
  });
  if (page === "results") {
    resultsNav.classList.remove("hidden");
    favoritesNav.classList.add("hidden");
  } else {
    resultsNav.classList.add("hidden");
    favoritesNav.classList.remove("hidden");
  }
  loader.classList.add("hidden");
}

// Create DOM Nodes
function createDOMNodes(page) {
  const currentArray =
    page === "results" ? resultsArray : Object.values(favorites);
  currentArray.forEach((result) => {
    // Card Container
    const card = document.createElement("div");
    card.classList.add("card");




    // Link that wraps the image
    const link = document.createElement("a");


    // Get the modal
    var modal = document.getElementById("myModal");

    // Get the image and insert it inside the modal - use its "alt" text as a caption
    var img = document.getElementById("myImg");
    var modalImg = document.getElementById("img01");

    var captionText = document.getElementById("caption");
    img.onclick = function() {
      modal.style.display = "block";



      modalImg.src = event.target.src;
      captionText.innerHTML = event.target.alt;

    }

    // Get the <span> element that closes the modal
    var span = document.getElementsByClassName("close")[0];

    // When the user clicks on <span> (x), close the modal
    span.onclick = function() {
      modal.style.display = "none";
    }


    // Image
    const image = document.createElement("img");
    image.src = result.url;
    // image.alt = "NASA Picture of the Day";
    image.alt = result.title + "<br>" + result.explanation + "<br>" + ' ' + result.date;
    image.loading = "lazy";
    image.classList.add("card-img-top");


    // Card Body
    const cardBody = document.createElement("div");
    cardBody.classList.add("card-body");

    // Card Title
    const cardTitle = document.createElement("h5");
    cardTitle.classList.add("card-title");
    cardTitle.textContent = result.title;

    // Save Text
    const saveText = document.createElement("p");
    saveText.classList.add("clickable");
    if (page === "results") {
      saveText.textContent = "Add To Favorites";
      saveText.setAttribute("onclick", `saveFavorite('${result.url}')`);
    } else {
      saveText.textContent = "Remove Favorite";
      saveText.setAttribute("onclick", `removeFavorite('${result.url}')`);
    }

    // Card Text
    const cardText = document.createElement("p");
    cardText.textContent = result.explanation;

    // Footer Conatiner
    const footer = document.createElement("small");
    footer.classList.add("text-muted");

    // Date
    const date = document.createElement("strong");
    date.textContent = result.date;

    // Copyright
    const copyrightResult =
      result.copyright === undefined ? "" : result.copyright;
    const copyright = document.createElement("span");
    copyright.textContent = ` ${copyrightResult}`;

    // Append everything together
    footer.append(date, copyright);
    cardBody.append(cardTitle, saveText, cardText, footer);
    link.appendChild(image);
    card.append(link); // hide cardBody

    // Append to image container
    imagesContainer.appendChild(card);
  });
}

// Update the DOM
function updateDOM(page) {
  // Get favorites from local storage
  if (localStorage.getItem("nasaFavorites")) {
    favorites = JSON.parse(localStorage.getItem("nasaFavorites"));
  }
  imagesContainer.textContent = "";
  createDOMNodes(page);
  showContent(page);
}

// Get 10 images from NASA API
async function getNasaPictures() {
  // Show Loader
  loader.classList.remove("hidden");
  try {
    const response = await fetch(apiUrl);
    resultsArray = await response.json();
    updateDOM("results");
  } catch (error) {
    // Catch Error Here
  }
}

// Add result to favorites
function saveFavorite(itemUrl) {
  // Loop through the results array to select favorite
  resultsArray.forEach((item) => {
    if (item.url.includes(itemUrl) && !favorites[itemUrl]) {
      favorites[itemUrl] = item;
      // Show save confirmation for 2 seconds
      saveConfirmed.hidden = false;
      setTimeout(() => {
        saveConfirmed.hidden = true;
      }, 2000);
      // Set Favorites in Local Storage
      localStorage.setItem("nasaFavorites", JSON.stringify(favorites));
    }
  });
}

// Remove item from favorites
function removeFavorite(itemUrl) {
  if (favorites[itemUrl]) {
    delete favorites[itemUrl];
    localStorage.setItem("nasaFavorites", JSON.stringify(favorites));
    updateDOM("favorites");
  }
}

// On Load
getNasaPictures();

正如@ba2sik 已经发布的那样,首先熟悉 localStorage API

您已经将整个 favorites 对象保存到 nasaFavorites 键下的本地存储中。 为了阅读它,每次要访问它时使用JSON.parse(localStorage.getItem('nasaFavorites'))反序列化内容。

请注意,上面的代码不处理边缘情况或错误,因此您可能希望使用 try/catch.

来处理它

编辑:这是对我之前的回答的编辑。这段代码应该可以帮助你。 (注意:此代码片段在这里不起作用,请从您的系统中尝试,因为此处不支持 localStorage。)

let nasaImages = [
    {
        id:1,
        url:"https://example.com/image-url-1"
    },
    {
        id:2,
        url:"https://example.com/image-url-2"
    },
    {
        id:3,
        url:"https://example.com/image-url-3"
    }
];

let favs = [];

//check if key exists in localstorage
if(localStorage.nasaFavs){
    favs = JSON.parse(localStorage.nasaFavs)
}

renderImages();



function renderImages(){
    $("#images").html(nasaImages.map(image => (
            `<div>
                id: ${image.id}
                <img src='${image.url}'>
                ${favBtn(image.id)}
            </div>`
        )
    ).join(""));
}


//render the fav button
function favBtn(id){
    if(favs.includes(id)){
        return `<button onclick="favUnfav(false,${id})">Remove from fav</button>`;
    }
    else{
        return `<button onclick="favUnfav(true,${id})">Add to fav</button>`;
    }
}


function favUnfav(isFav=true, id=null){
    //write your logic to add to fav or remove from fav
    if(isFav){
        favs.push(id);
    }
    else{
        favs = favs.filter(e => e!=id);
    }

    //save in localstorage
    localStorage.nasaFavs = JSON.stringify(favs);

    //re render the DOM
    renderImages()
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="images"></div>

一个有趣的问题,我检查了 Nasa.api,我发现服务器会 return 你一个包含 objectarray,所以一个好的选择是使用一个array来存储所有喜欢的项目,它会更容易显示。

我给你的建议是直接把nasa.api给你的信息存到数组里存到localStorage里。以后你展示会更方便

我还为您创建了一个使用 nasa.api 的示例,您可以使用它,因为我没有您的完整代码以及您如何获得 code/display 它,但您可以看到我如何修改 localStorage

的部分

所以在我创建的示例中,每次用户单击喜欢的按钮时,它都会保存到 liked(数组)并保存到 localStorage。每隔两次,用户单击按钮,我们将从 liked 数组中删除该项目并更新 localStorage。

let source;
let xhr = new XMLHttpRequest();
let link = "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&count=5"
xhr.open('GET', link, true);
xhr.send();
let liked = JSON.parse(localStorage.getItem("likeditem"));

if (liked == null) liked = [];
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    source = JSON.parse(xhr.responseText);
    create()
  }
} //Check if liked is null, if it is, assign empty array value to it.

function create() {
  for (let i = 0; i < source.length; i++) {
    console.log(source[i])
    document.body.innerHTML += `
         <img src=${source[i].url}>
         <div >${source[i].title}</div>
         <div >Date: ${source[i].date}</div>
          <div>Copyright: ${source[i].copyright}</div>
          <div>Media_type: ${source[i].media_type}</div>
          <div>Service_version: ${source[i].service_version}</div>
         <div>Explanation: ${source[i].explanation}</div>
          <button onclick='save(${i})'>Save to like</button>
`
    //TO save/remove liked item from local Storage when button clicked
    window.save = function(index) {
      let thisbutton = document.querySelectorAll('button')[index]
      if (thisbutton.textContent == 'Save to like') {
        liked.push(source[index])
        localStorage.setItem('likeditem', JSON.stringify(liked));
        thisbutton.textContent = "Saved"
      } else {
        //Remove it from local storage when user click it every two times
        liked.splice(liked.indexOf(source[index]), 1)
        localStorage.setItem('likeditem', JSON.stringify(liked));
        thisbutton.textContent = 'Save to like'
      }
    }
  }
}

关于如何显示localStorage中的元素,也有一个例子。

我们之前已经将所有关于图像的信息保存到localStorage,所以我们只使用我们显示来自nasa.api的信息的方式。

let liked = JSON.parse(localStorage.getItem("likeditem"));

for (let i in liked){
//Immediately return the for loop if no value stored in loal storage
if(!liked) break;;
        document.body.innerHTML += `
         <img src=${liked[i].url}>
         <div >${liked[i].title}</div>
         <div >Date: ${liked[i].date}</div>
          <div>Copyright: ${liked[i].copyright}</div>
          <div>Media_type: ${liked[i].media_type}</div>
          <div>Service_version: ${liked[i].service_version}</div>
         <div>Explanation: ${liked[i].explanation}</div>
          `
}

更新:

保存到本地存储:

从 localStorage 显示: