Descargar código
La idea consiste en tener objetos que representen las acciones (mover, eliminar, resaltar...), los cuales deben guardar el estado anterior del objeto afectado.
ChangeColorCommand = function(obj, color) { this.obj = obj; this.new_color = color; // guardar estado anterior this.prev_color = obj.style.backgroundColor; } ChangeColorCommand.prototype.execute = function() { this.obj.style.backgroundColor = this.new_color; } ChangeColorCommand.prototype.undo = function() { this.obj.style.backgroundColor = this.prev_color; }Cada objeto cuenta con dos métodos
- execute: ejecuta la acción (dah)
- undo: deshace la acción valiéndose de los datos guardados previamente en el constructor.
- cuando ejecuta una acción, la guarda en undo_stack y borra toda acción que se podía rehacer
- cuando se deshace algo, saca el ultimo objeto de la pila undo_stack, ejecuta el método undo y guarda la acción en la pila redo_stack.
CommandManager = function(max_undo) { // máxima cantidad de acciones guardadas max_undo = max_undo || 30; // pilas de acciones this.undo_stack = []; this.redo_stack = []; // ejecutar comando cmd this.executeCommand = function(cmd){ cmd.execute(); // si se sobrepasa cantidad de acciones // eliminar primer elemento if (this.undo_stack.length >= max_undo) { this.undo_stack.shift(); } this.undo_stack.push(cmd); this.redo_stack = []; } // deshacer acción this.undoCommand = function() { var cmd = this.undo_stack.pop(); // si existe acción if ( cmd ) { cmd.undo(); this.redo_stack.push(cmd); } } }Para realizar una acción creamos una instancia del objeto apropiado y la pasamos al CommandManager (previamente creado).
var UndoRedo = new CommandManager(), box = document.getElementById("box"); // cambiar color a rojo UndoRedo.executeCommand(new ChangeColorCommand(box, "red")); // cambiar color a verde UndoRedo.executeCommand(new ChangeColorCommand(box, "green")); // cambiar de verde a rojo UndoRedo.undoCommand(); // cambiar de rojo a blanco UndoRedo.undoCommand();Ahora solo resta crear mas acciones (mover, negrita, itálica...) dependiendo de la aplicación que estemos desarrollando.
Eso es todo, espero les haya servido; si tienen alguna duda o critica no duden en dejarla en los comentarios.