如何将创建的闪卡保存到localStorage并在刷新后恢复显示?
修复闪卡项目的localStorage持久化问题
你的代码存在几个核心问题导致闪卡无法在刷新后保留:页面加载时未读取localStorage恢复内容、直接存储HTML导致事件监听丢失、删除卡片后未同步更新存储数据,以及类名判断逻辑不够健壮。下面是完整的修复方案:
修改后的完整代码
HTML(无改动)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Flashcards</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <div class="inner-container"> <div class="header"> <h1>Flashcards</h1> <button id="add-question">Add Question</button> </div> <div class="hidden"> <div class="innerForm-container"> <form action=""> <h2>Question</h2> <textarea name="" id="question-input" cols="30" rows="10"></textarea> <h2>Answer</h2> <textarea name="" id="answer-input" cols="30" rows="10"></textarea> <button id="save-btn">Save</button> <button id="close-btn">X</button> </form> </div> </div> <div class="grid-cards"> </div> </div> </div> <script src="main.js"></script> </body> </html>
CSS(无改动)
* { padding: 0; margin: 0; box-sizing: border-box; } body { display: flex; justify-content: center; } .container { max-width: 1100px; width: 100%; } .header { padding: 25px 0; } #add-question { margin-top: 15px; padding: 10px 15px; } .innerForm-container { background-color: rgb(219, 219, 219); padding: 20px; width: 500px; border: 2px solid black; position: relative; } h2 { margin-top: 10px; } #question-input { margin-top: 10px; width: 100%; height: 70px; } #answer-input { margin-top: 10px; width: 100%; height: 70px; } #save-btn { margin-top: 15px; padding: 10px 100px; } #close-btn { position: absolute; top: 5px; right: 5px; padding: 15px 20px; } .hidden { display: none; } .grid-cards { display: grid; grid-template-columns: repeat(3, 350px); grid-template-rows: repeat(5, 200px); grid-column-gap: 25px; grid-row-gap: 25px; justify-content: center; margin-top: 20px; } .card { background-color: rgb(230, 230, 230); border: 1px solid black; border-radius: 15px; padding: 15px; position: relative; } h3 { font-size: 22px; } p { margin-top: 15px; } a { margin-top: 25px; display: block; } #deleteBtn { padding: 10px 20px; position: absolute; bottom: 15px; right: 15px; }
JavaScript(核心修改)
// DOM元素获取 const addQuestionBtn = document.querySelector("#add-question") const formContainer = document.querySelector(".hidden") const closeBtn = document.querySelector("#close-btn") const questionInput = document.querySelector("#question-input") const answerInput = document.querySelector("#answer-input") const form = document.querySelector("form") const grid = document.querySelector(".grid-cards") // 表单显示/隐藏切换 addQuestionBtn.addEventListener("click", function() { formContainer.classList.toggle("hidden") formContainer.classList.toggle("form-container") }) closeBtn.addEventListener("click", function() { formContainer.classList.add("hidden") formContainer.classList.remove("form-container") }) // 从localStorage加载闪卡数据 function loadFlashcards() { const cards = JSON.parse(localStorage.getItem("flashcards")) || [] cards.forEach(card => createCard(card.question, card.answer)) } // 创建单个闪卡元素并绑定事件 function createCard(question, answer) { // 创建元素 const div = document.createElement("div") div.classList.add("card") const h3 = document.createElement("h3") h3.setAttribute("id", "question") const showHideAnswer = document.createElement("a") showHideAnswer.setAttribute("href", "") showHideAnswer.textContent = "Show/Hide Answer" const p = document.createElement("p") p.classList.add("hidden") const deleteBtn = document.createElement("button") deleteBtn.setAttribute("id", "deleteBtn") // 设置内容 h3.textContent = question p.textContent = answer deleteBtn.textContent = "Delete" // 组装元素 div.append(h3, showHideAnswer, p, deleteBtn) grid.appendChild(div) // 显示/隐藏答案事件 showHideAnswer.addEventListener("click", function(e) { e.preventDefault() p.classList.toggle("hidden") p.classList.toggle("answer") }) // 删除闪卡事件 deleteBtn.addEventListener("click", function() { grid.removeChild(div) // 更新localStorage数据 updateFlashcards() }) } // 更新localStorage中的闪卡数据 function updateFlashcards() { const cards = [] document.querySelectorAll(".card").forEach(card => { const question = card.querySelector("#question").textContent const answer = card.querySelector("p").textContent cards.push({ question, answer }) }) localStorage.setItem("flashcards", JSON.stringify(cards)) } // 表单提交创建闪卡 form.addEventListener("submit", function(e) { e.preventDefault() const question = questionInput.value.trim() const answer = answerInput.value.trim() if (question && answer) { createCard(question, answer) // 清空输入框 questionInput.value = "" answerInput.value = "" // 关闭表单 formContainer.classList.add("hidden") formContainer.classList.remove("form-container") // 更新localStorage updateFlashcards() } }) // 页面加载时加载闪卡 window.addEventListener("DOMContentLoaded", loadFlashcards)
关键改动说明
- 数据存储方式优化:不再存储HTML结构,改为存储闪卡的问题和答案组成的JSON数组,避免刷新后事件监听丢失
- 新增加载逻辑:页面初始化时调用
loadFlashcards从localStorage读取数据,重建所有闪卡 - 封装创建卡片逻辑:将创建卡片和绑定事件的代码抽成独立函数,确保动态创建和重建的卡片都能正常响应交互
- 删除同步更新:删除卡片后立即调用
updateFlashcards重新收集数据并更新存储,避免删除的卡片刷新后重现 - 简化类名操作:使用
classList.toggle替代手动判断类名,代码更简洁健壮 - 添加输入验证:避免创建内容为空的闪卡
内容的提问来源于stack exchange,提问作者Chase Hudson
相关产品推荐
相关产品推荐

