JavaScript中对象数组存入localStorage后读取为空?需保序实现撤销功能
问题分析与解决方法
问题原因
你直接将DOM元素(img1、img2这类HTMLElement对象)存入localStorage,而JSON.stringify无法正常序列化DOM元素——DOM元素的内部属性大多不可枚举,最终只能被转换成空对象{},导致localStorage中存储的是[{},{}],读取后自然得到空对象数组。
解决思路
要实现撤销功能,你需要保存的是DOM元素的关键状态数据(而非元素本身),比如图片的src、alt、位置样式等。这类基础数据类型(字符串、数字、普通对象)可以被JSON正常序列化,同时能严格保留数组顺序,满足撤销操作的需求。
修改后的代码示例
保存状态(saveGame)
先把DOM元素转换成包含关键状态的普通对象,再存入localStorage:
const img1 = document.getElementById("img1"); // img标签 const img2 = document.getElementById("img2"); // img标签 // 提取DOM元素的关键状态 function getElementState(img) { return { id: img.id, // 用于后续匹配回原DOM元素 src: img.src, alt: img.alt, style: { left: img.style.left, top: img.style.top // 添加你需要保存的其他状态,比如宽高、类名等 } }; } function saveGame(){ const stateArr = [getElementState(img1), getElementState(img2)]; localStorage.setItem("savedgameHistory", JSON.stringify(stateArr)); window.location.href = "./TicTacToe.html"; }
加载状态(loadGame)
读取存储的状态数据,将其还原到对应的DOM元素上:
function loadGame(){ const history = JSON.parse(localStorage.getItem("savedgameHistory")); if (!history) return; // 遍历状态数组,还原每个元素的状态 history.forEach(state => { const targetImg = document.getElementById(state.id); if (targetImg) { targetImg.src = state.src; targetImg.alt = state.alt; targetImg.style.left = state.style.left; targetImg.style.top = state.style.top; // 还原其他保存的状态 } }); }
扩展:实现多步撤销功能
如果要支持多步撤销,需要维护一个历史状态栈,每一步操作都将当前完整状态推入栈中,撤销时取出上一步状态还原:
// 全局维护历史状态栈,初始可以存入初始状态 let historyStack = []; // 保存当前状态到历史栈 function saveCurrentState() { const currentState = [getElementState(img1), getElementState(img2)]; historyStack.push(currentState); localStorage.setItem("savedgameHistory", JSON.stringify(historyStack)); } // 撤销操作 function undo() { if (historyStack.length <= 1) return; // 保留初始状态,不能再撤销 historyStack.pop(); // 移除当前状态,回到上一步 const lastValidState = historyStack[historyStack.length - 1]; // 还原上一步状态到DOM lastValidState.forEach(state => { const targetImg = document.getElementById(state.id); if (targetImg) { targetImg.src = state.src; targetImg.alt = state.alt; targetImg.style.left = state.style.left; targetImg.style.top = state.style.top; } }); // 更新localStorage中的历史栈 localStorage.setItem("savedgameHistory", JSON.stringify(historyStack)); }
内容的提问来源于stack exchange,提问作者Yoan
相关产品推荐
相关产品推荐

