js实现封装历史记录功能,支持撤回、重做、清空等操作,可在其他任何需要历史记录的系统中使用.
实现历史记录class版
// 最大历史栈长度
const MAX_HISTORY_LENGTH = 100;
// 获取数组最后一个元素
const last = (arr) => arr[arr.length - 1];
// 清空数组
const clear = (arr) => arr.splice(0, arr.length);
class History {
constructor(maxLength = MAX_HISTORY_LENGTH) {
// 历史记录栈
this.stack = [];
// 撤销栈
this.undoStack = [];
// 最新的值
this.currentValue = null;
// 最大历史栈长度
this.maxLength = maxLength;
}
/**
* 是否满
*/
isFull() {
return this.stack.length >= this.maxLength;
}
/**
* 添加历史记录
* @param {*} value 历史记录值
*/
push(value) {
this.stack.push(value);
this.undoStack = [];
this.currentValue = value;
if (this.stack.length > this.maxLength) {
this.stack.splice(0, 1);
}
}
/**
* 撤销
*/
undo() {
if (this.stack.length === 0) {
return;
}
const value = this.stack.pop();
this.undoStack.push([value]);
this.currentValue = last(this.stack);
}
/**
* 重做
*/
redo() {
if (this.undoStack.length === 0) {
return;
}
const valueList = this.undoStack.pop();
this.stack.push(...valueList);
this.currentValue = last(this.stack);
}
/**
* 清空历史栈
*/
clear() {
this.undoStack.push([ ...this.stack ]);
this.stack = [];
}
}
复制代码
构造函数版
- 历史栈为私有属性,避免被外部直接修改导致出错
/**
* 历史记录构造函数版(栈为私有属性)
* @param {number} maxLength 最大长度
*/
function HistoryFun (maxLength = MAX_HISTORY_LENGTH) {
// 历史记录栈
const stack = [];
// 撤销栈
const undoStack = [];
// 最新的值
this.currentValue = null;
/**
* 满
*/
this.isFull = () => {
return stack.length >= maxLength;
};
/**
* 历史栈长度
*/
this.getLength = () => {
return stack.length;
}
/**
* 获取历史栈
*/
this.getHistoryStack = () => {
return [ ...stack ];
}
/**
* 获取撤销栈
*/
this.getUndoStack = () => {
return [ ...undoStack ];
}
/**
* 添加历史记录
* @param {*} value 历史记录值
*/
this.push = (value) => {
stack.push(value);
clear(undoStack);
this.currentValue = value;
if (stack.length > this.maxLength) {
stack.splice(0, 1);
}
};
/**
* 撤销
*/
this.undo = () => {
if (stack.length === 0) {
return;
}
const value = stack.pop();
undoStack.push([value]);
this.currentValue = last(stack);
};
/**
* 重做
*/
this.redo = () => {
if (undoStack.length === 0) {
return;
}
const valueList = undoStack.pop();
stack.push(...valueList);
this.currentValue = last(stack);
};
/**
* 清空历史栈
*/
this.clear = () => {
undoStack.push([...stack]);
clear(stack);
};
}
复制代码
使用
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(); // [] [[3], [1,2]]
history.redo(); // [1,2] [[3]]
history.redo(); // [1,2,3] []
复制代码
演示
为了方便理解做了一个demo,通过点击按钮进行历史记录的操作操作。
链接如下:历史记录演示demo