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