电影收藏夹项目:如何将HTML数据存入LocalStorage并在另一页面展示
解决跨页面电影收藏LocalStorage持久化与DOM渲染问题
问题根源拆解
- 存储逻辑错误:直接把单条电影的HTML字符串存在LocalStorage,不仅会被新收藏内容覆盖,还无法管理已收藏列表(比如删除操作)。
- 跨页面DOM操作无效:搜索页里没有收藏页的
#moviesToo元素,直接调用document.querySelector('#moviesToo')必然返回null——浏览器一次仅加载当前页面的DOM。 - 收藏页未初始化渲染:收藏页加载时没有主动读取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
相关产品推荐
相关产品推荐

