You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

电影收藏夹项目:如何将HTML数据存入LocalStorage并在另一页面展示

解决跨页面电影收藏LocalStorage持久化与DOM渲染问题

问题根源拆解

  1. 存储逻辑错误:直接把单条电影的HTML字符串存在LocalStorage,不仅会被新收藏内容覆盖,还无法管理已收藏列表(比如删除操作)。
  2. 跨页面DOM操作无效:搜索页里没有收藏页的#moviesToo元素,直接调用document.querySelector('#moviesToo')必然返回null——浏览器一次仅加载当前页面的DOM。
  3. 收藏页未初始化渲染:收藏页加载时没有主动读取LocalStorage数据并渲染,导致看不到已收藏内容。

修正方案

1. 改用电影ID数组存储收藏列表

LocalStorage只存收藏电影的imdbID数组,既节省空间,又方便后续增删和重新渲染。

2. 分离页面逻辑

通过判断当前页面是否存在特定DOM元素(比如搜索页的#search按钮、收藏页的#moviesToo容器),决定执行对应逻辑,避免无效DOM操作。

3. 收藏页初始化渲染

收藏页加载时,读取LocalStorage中的ID数组,批量获取电影数据并渲染。

4. 实现收藏/删除功能

点击加号时将ID加入数组,点击减号时从数组移除,每次操作后更新LocalStorage并重新渲染对应页面内容。


修改后的完整代码

// 通用工具函数:获取LocalStorage中的收藏列表
function getWatchlist() {
  return JSON.parse(localStorage.getItem('watchlist')) || [];
}

// 通用工具函数:更新LocalStorage中的收藏列表
function updateWatchlist(newList) {
  localStorage.setItem('watchlist', JSON.stringify(newList));
}

// 搜索页逻辑
function initSearchPage() {
  const searchBtn = document.querySelector("#search");
  if (!searchBtn) return; // 不是搜索页,直接退出

  searchBtn.addEventListener('click', async function(){
    const movSearch = document.querySelector("#movieSearch").value;
    const res = await fetch(`https://www.omdbapi.com/?s=${movSearch}&type=Movie&apikey=3c746e2`);
    const data = await res.json();

    const movArr = data.Search;
    let html = "";
    
    for(let movie of movArr) {
      const rez = await fetch(`https://www.omdbapi.com/?i=${movie.imdbID}&type=Movie&apikey=3c746e2`);
      const datatwo = await rez.json();
      
      html += `
        <div class="movieInput" style="display:flex;align-items:center">
          <div> 
            <img src="${movie.Poster}" style="width:99px;margin:42px 0 0 44px">
          </div>
          <div></div>
          <div style="margin:3px 0 0 21px">
            <text style="font-weight:bold; font-size:18px">${movie.Title}</text>
            <p>${datatwo.imdbRating}</p>
            <div style="display:flex; gap:36px; font-size:12px"> 
              <p>${datatwo.Runtime}</p> 
              <p>${datatwo.Genre}</p> 
              <p><i class="fa-solid fa-circle-plus" data-add="${datatwo.imdbID}"></i></p>
            </div>
            <div style="margin:-20px 0 0 0">
              <p>${datatwo.Plot}</p>
            </div> 
          </div>
        </div>
        <hr />`;
    }
    document.querySelector("#movies").innerHTML = html;
  });
}

// 收藏页逻辑:初始化渲染收藏列表
function initWatchlistPage() {
  const watchlistContainer = document.querySelector('#moviesToo');
  if (!watchlistContainer) return; // 不是收藏页,直接退出

  async function renderWatchlist() {
    const watchlistIds = getWatchlist();
    if (watchlistIds.length === 0) {
      watchlistContainer.innerHTML = "<p>暂无收藏电影</p>";
      return;
    }

    let html = "";
    for (let id of watchlistIds) {
      const res = await fetch(`https://www.omdbapi.com/?i=${id}&type=Movie&apikey=3c746e2`);
      const movie = await res.json();
      
      html += `
        <div class="movieInput" style="display:flex;align-items:center">
          <div> 
            <img src="${movie.Poster}" style="width:99px;margin:42px 0 0 44px">
          </div>
          <div></div>
          <div style="margin:3px 0 0 21px">
            <text style="font-weight:bold; font-size:18px">${movie.Title}</text>
            <p>${movie.imdbRating}</p>
            <div style="display:flex; gap:36px; font-size:12px"> 
              <p>${movie.Runtime}</p> 
              <p>${movie.Genre}</p> 
              <p><i class="fa-solid fa-circle-minus" data-remove="${movie.imdbID}"></i></p>
            </div>
            <div style="margin:-20px 0 0 0">
              <p>${movie.Plot}</p>
            </div> 
          </div>
        </div>
        <hr />`;
    }
    watchlistContainer.innerHTML = html;
  }

  // 页面加载时渲染收藏列表
  renderWatchlist();

  // 监听删除按钮点击
  document.addEventListener('click', function(e) {
    if (e.target.dataset.remove) {
      const idToRemove = e.target.dataset.remove;
      const currentList = getWatchlist();
      const newList = currentList.filter(id => id !== idToRemove);
      updateWatchlist(newList);
      renderWatchlist(); // 重新渲染
    }
  });
}

// 监听收藏按钮点击(全局,搜索页触发)
function initWatchlistActions() {
  document.addEventListener('click', async function(e) {
    if (e.target.dataset.add) {
      const idToAdd = e.target.dataset.add;
      const currentList = getWatchlist();
      if (!currentList.includes(idToAdd)) { // 避免重复收藏
        currentList.push(idToAdd);
        updateWatchlist(currentList);
        alert("已加入收藏");
      }
    }
  });
}

// 初始化所有逻辑
initSearchPage();
initWatchlistPage();
initWatchlistActions();

关键修改说明

  • 存储结构优化:用数组存储imdbID,替代原有的HTML字符串存储,增删和渲染更灵活。
  • 页面逻辑分离:通过判断页面特有DOM元素,仅执行当前页面所需代码,避免无效操作。
  • 收藏页主动渲染:页面加载时自动读取LocalStorage并渲染内容,解决刷新后无数据的问题。
  • 去重处理:收藏时判断ID是否已存在,避免重复添加。

内容的提问来源于stack exchange,提问作者ohio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 09:20:27