Js to achieve the function of packaging history, support to withdraw, redo, clear operations, can be used in any other system that requires history.
Implement the History Class version
// Maximum stack length
const MAX_HISTORY_LENGTH = 100;
// Get the last element of the array
const last = (arr) = > arr[arr.length - 1];
// Empty the array
const clear = (arr) = > arr.splice(0, arr.length);
class History {
constructor(maxLength = MAX_HISTORY_LENGTH) {
// The history stack
this.stack = [];
/ / undo stack
this.undoStack = [];
// The latest value
this.currentValue = null;
// Maximum stack length
this.maxLength = maxLength;
}
/** * is full */
isFull() {
return this.stack.length >= this.maxLength;
}
/** * Add history *@param {*} Value Historical value */
push(value) {
this.stack.push(value);
this.undoStack = [];
this.currentValue = value;
if (this.stack.length > this.maxLength) {
this.stack.splice(0.1); }}/** * revoke */
undo() {
if (this.stack.length === 0) {
return;
}
const value = this.stack.pop();
this.undoStack.push([value]);
this.currentValue = last(this.stack);
}
/** * redo */
redo() {
if (this.undoStack.length === 0) {
return;
}
const valueList = this.undoStack.pop();
this.stack.push(... valueList);this.currentValue = last(this.stack);
}
/** * Clear the history stack */
clear() {
this.undoStack.push([ ...this.stack ]);
this.stack = []; }}Copy the code
Constructor edition
- The history stack is a private property to avoid errors caused by direct external modification
/** * History constructor version (stack is private) *@param {number} MaxLength Indicates the maximum length */
function HistoryFun (maxLength = MAX_HISTORY_LENGTH) {
// The history stack
const stack = [];
/ / undo stack
const undoStack = [];
// The latest value
this.currentValue = null;
/ * * * * /
this.isFull = () = > {
return stack.length >= maxLength;
};
/** * Historical stack length */
this.getLength = () = > {
return stack.length;
}
/** * get the history stack */
this.getHistoryStack = () = > {
return [ ...stack ];
}
/** * get undo stack */
this.getUndoStack = () = > {
return [ ...undoStack ];
}
/** * Add history *@param {*} Value Historical value */
this.push = (value) = > {
stack.push(value);
clear(undoStack);
this.currentValue = value;
if (stack.length > this.maxLength) {
stack.splice(0.1); }};/** * revoke */
this.undo = () = > {
if (stack.length === 0) {
return;
}
const value = stack.pop();
undoStack.push([value]);
this.currentValue = last(stack);
};
/** * redo */
this.redo = () = > {
if (undoStack.length === 0) {
return;
}
constvalueList = undoStack.pop(); stack.push(... valueList);this.currentValue = last(stack);
};
/** * Clear the history stack */
this.clear = () = > {
undoStack.push([...stack]);
clear(stack);
};
}
Copy the code
use
const history = new History(10);
history.push(1); // [1] []
history.push(2); / / [1, 2] []
history.push(3); / / [1, 2, 3] []
history.undo(); / / [1, 2], [[3]]
history.undo(); / / [1], [[3], [2]]
history.redo(); / / [1, 2], [[3]]
history.clear(); / / [] to [[3], [1, 2]]
history.redo(); / / [1, 2], [[3]]
history.redo(); / / [1, 2, 3] []
Copy the code
demo
In order to facilitate the understanding of a demo, by clicking the button to record the operation of the history.
The link is as follows: History demo