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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 20:15:16