如何使用js实现撤消和重做并写出伪代码

在前端开发中,使用 JavaScript 实现撤销和重做功能,通常采用命令模式。 核心思想是将每一个操作封装成一个命令对象,并用两个栈分别存储已执行的命令(用于撤销)和已撤销的命令(用于重做)。

以下是使用 JavaScript 实现撤销和重做的伪代码:

// 定义命令对象
class Command {
  constructor(execute, undo, value) {
    this.execute = execute; // 执行操作的函数
    this.undo = undo;     // 撤销操作的函数
    this.value = value;   // 操作相关的参数
  }
}

// 撤销/重做管理器
class History {
  constructor() {
    this.undoStack = [];  // 撤销栈
    this.redoStack = [];  // 重做栈
  }

  execute(command) {
    command.execute(command.value);
    this.undoStack.push(command);
    this.redoStack.length = 0; // 执行新命令后,清空重做栈
  }

  undo() {
    if (this.undoStack.length > 0) {
      const command = this.undoStack.pop();
      command.undo(command.value);
      this.redoStack.push(command);
    } else {
      console.log("Nothing to undo.");
    }
  }

  redo() {
    if (this.redoStack.length > 0) {
      const command = this.redoStack.pop();
      command.execute(command.value);
      this.undoStack.push(command);
    } else {
      console.log("Nothing to redo.");
    }
  }
}


// 示例用法:假设操作是修改文本框内容

const history = new History();
const textInput = document.getElementById('myTextInput'); // 获取文本框元素

// 定义修改文本的命令
function setText(text) {
  textInput.value = text;
}

function undoSetText(previousText) {
  textInput.value = previousText;
}


// 监听文本框输入事件
textInput.addEventListener('input', (event) => {
  const newText = event.target.value;
  const oldText = event.target.dataset.previousValue || ""; // 获取之前的文本,初始为空

  const command = new Command(setText, undoSetText, {newText: newText, oldText: oldText});
  history.execute(command);

  // 更新之前的文本
  event.target.dataset.previousValue = newText;
});


// 绑定撤销和重做按钮
document.getElementById('undoButton').addEventListener('click', () => history.undo());
document.getElementById('redoButton').addEventListener('click', () => history.redo());


关键点解释:

  • 命令对象: 封装了操作的执行和撤销逻辑,以及操作所需的数据。
  • 两个栈: undoStack 存储已执行的命令,redoStack 存储已撤销的命令。
  • execute(): 执行命令,将其添加到 undoStack,并清空 redoStack
  • undo():undoStack 弹出一个命令执行其撤销逻辑,并将该命令添加到 redoStack
  • redo():redoStack 弹出一个命令执行其执行逻辑,并将该命令添加到 undoStack
  • 示例用法: 演示了如何将该模式应用于修改文本框内容的场景。 注意如何保存之前的文本以便撤销。

这个伪代码提供了一个基本的撤销/重做框架。实际应用中,你需要根据具体的操作类型定义相应的命令对象和执行/撤销逻辑。 例如,对于图形编辑器,命令可能包括添加形状、移动形状、改变颜色等。 对于富文本编辑器,命令可能包括插入文本、删除文本、修改格式等。

这个例子使用了 input 事件监听每次输入的变化. 对于性能敏感的场景,可以考虑使用 keydownkeyup 事件配合节流或防抖技术,或者在用户完成输入一段落后再记录操作,以减少命令对象的创建和栈的操作次数。

posted @   王铁柱6  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示