编辑器增加撤销、重做功能开发
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
<template v-else-if="!!item.text">{{item.text}}</template>
|
||||
<br v-else/>
|
||||
</div>
|
||||
<div v-else-if="item.type=='locate'" :class="item.cls" @click.stop="domClick(item, $event)">
|
||||
<div v-else-if="item.type=='locate'" :class="item.cls" :index="index" @click.stop="domClick(item, $event)">
|
||||
<br/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -91,7 +91,7 @@
|
||||
this.userInput.addEventListener('keydown', e => {
|
||||
if (e.which == 13) {
|
||||
e.preventDefault();
|
||||
this.editDom.keyEnter(this.editorDom, this.editorRange);
|
||||
this.editDom.keyEnter(this.editorDom, this.editorRange, this.undoRedo);
|
||||
} else if (e.keyCode == 90 && e.ctrlKey) {
|
||||
e.preventDefault();
|
||||
this.undoRedo.undo();
|
||||
@@ -164,6 +164,7 @@
|
||||
if (lastDom.type != 'locate') {
|
||||
lastDom = new Dom('locate', 'locate');
|
||||
this.editorDom.push(lastDom);
|
||||
this.undoRedo.execute(2, this.editorDom.length - 1, JSON.stringify(lastDom), '');
|
||||
}
|
||||
setTimeout(() => event.target.lastChild.click(), 100);
|
||||
},
|
||||
@@ -220,10 +221,12 @@
|
||||
userInputDataChange() {
|
||||
if (!this.userInputData) return;
|
||||
// 如果在最后一个div里面输入,则改为非最后一个,然后在最后再加一行
|
||||
let domNew;
|
||||
if (this.editDom.type == 'locate') {
|
||||
this.editDom.type = 'text';
|
||||
this.editDom.removeClass('locate');
|
||||
this.editorDom.push(new Dom('locate', 'locate'));
|
||||
domNew = new Dom('locate', 'locate');
|
||||
this.editorDom.push(domNew);
|
||||
}
|
||||
let beforeJson = JSON.stringify(this.editDom);
|
||||
let oldText = this.editDom.text || '';
|
||||
@@ -244,6 +247,10 @@
|
||||
let editDomNode = toolbarCommon.getRootDom(this.editDom.target);
|
||||
let editIndex = parseInt(editDomNode.getAttribute("index"));
|
||||
this.undoRedo.execute(1, editIndex, beforeJson, afterJson);
|
||||
// 如果在最后一个div里面输入,则改为非最后一个,然后在最后再加一行
|
||||
if (!!domNew) {
|
||||
this.undoRedo.execute(2, this.editorDom.length - 1, JSON.stringify(domNew), '');
|
||||
}
|
||||
},
|
||||
handleToolbarBold() {
|
||||
for (let i = this.editorRange.startDomIndex; i < this.editorRange.endDomIndex; i++) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// 构造函数
|
||||
import StyleRange from "./styleRange";
|
||||
import toolbarCommon from "../../editor/toolbar/common";
|
||||
|
||||
function Dom(type = 'text', cls = '', text = '', styleRange = []) {
|
||||
this.type = type;
|
||||
@@ -128,20 +129,21 @@ Dom.prototype = {
|
||||
}
|
||||
},
|
||||
// 回车事件处理
|
||||
keyEnter(editorDom, editorRange) {
|
||||
keyEnter(editorDom, editorRange, undoRedo) {
|
||||
let nextText = '';
|
||||
let oldText = this.text || '';
|
||||
// 如果文字的中间位置点击,则把内容分割到两行
|
||||
if (editorRange.startOffset < oldText.length) {
|
||||
let beforeJson = JSON.stringify(this);
|
||||
this.text = oldText.substring(0, editorRange.startOffset);
|
||||
undoRedo.execute(1, editIndex, beforeJson, JSON.stringify(this));
|
||||
nextText = oldText.substring(editorRange.startOffset, oldText.length);
|
||||
}
|
||||
for (let i = 0; i < editorDom.length; i++) {
|
||||
if (this == editorDom[i]) {
|
||||
editorDom.splice(i + 1, 0, new Dom('text', this.cls, nextText));
|
||||
break;
|
||||
}
|
||||
}
|
||||
let editDomNode = toolbarCommon.getRootDom(this.target);
|
||||
let editIndex = parseInt(editDomNode.getAttribute("index"));
|
||||
let domNew = new Dom('text', this.cls, nextText);
|
||||
editorDom.splice(editIndex + 1, 0, domNew);
|
||||
undoRedo.execute(2, editIndex + 1, JSON.stringify(domNew), '');
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import UndoInfo from "./undoInfo";
|
||||
import Dom from "./dom";
|
||||
import vue from '../../../main'
|
||||
|
||||
function UndoRedo(editorDom) {
|
||||
this.editorDom = editorDom;
|
||||
@@ -13,15 +14,19 @@ function UndoRedo(editorDom) {
|
||||
UndoRedo.prototype = {
|
||||
constructor: UndoRedo,
|
||||
execute(type, index, before, after) {
|
||||
// 最多保留20步
|
||||
if (this.undoRedoList.length >= 20) {
|
||||
// 忽略后面的操作步骤
|
||||
if (this.undoRedoIndex >= 0 && this.undoRedoIndex < this.undoRedoList.length - 1) {
|
||||
this.undoRedoList.splice(this.undoRedoIndex, this.undoRedoList.length - this.undoRedoIndex);
|
||||
}
|
||||
// 最多保留50步
|
||||
if (this.undoRedoList.length >= 50) {
|
||||
this.undoRedoList.splice(0, 1);
|
||||
}
|
||||
this.undoRedoList.push(new UndoInfo(type, index, before, after));
|
||||
this.undoRedoIndex = this.undoRedoList.length - 1;
|
||||
},
|
||||
undo() {
|
||||
if (this.undoRedoIndex < 0 || this.undoRedoIndex >= this.undoRedoList.length) {
|
||||
if (this.undoRedoIndex >= this.undoRedoList.length) {
|
||||
this.undoRedoIndex = this.undoRedoList.length - 1;
|
||||
}
|
||||
if (this.undoRedoIndex < 0) {
|
||||
@@ -36,7 +41,7 @@ UndoRedo.prototype = {
|
||||
} else {
|
||||
this.undoObjDomToEditor(undoInfo, changeContent);
|
||||
}
|
||||
this.undoRedoIndex = Math.max(this.undoRedoIndex - 1, 0);
|
||||
this.undoRedoIndex = Math.max(this.undoRedoIndex - 1, -1);
|
||||
},
|
||||
redo() {
|
||||
this.undoRedoIndex++;
|
||||
@@ -45,7 +50,8 @@ UndoRedo.prototype = {
|
||||
return;
|
||||
}
|
||||
let undoInfo = this.undoRedoList[this.undoRedoIndex];
|
||||
let changeContent = JSON.parse(undoInfo.after);
|
||||
let actionText = (undoInfo.type == 1) ? undoInfo.after : undoInfo.before;
|
||||
let changeContent = JSON.parse(actionText);
|
||||
if (changeContent instanceof Array) {
|
||||
changeContent.forEach(item => {
|
||||
this.redoObjDomToEditor(undoInfo, item);
|
||||
@@ -59,16 +65,14 @@ UndoRedo.prototype = {
|
||||
if (undoInfo.type == 1) {
|
||||
// 1=修改 2=添加 3=删除
|
||||
if (this.editorDom.length > undoInfo.index) {
|
||||
this.editorDom[undoInfo.index] = dom;
|
||||
vue.$set(this.editorDom, undoInfo.index, dom);
|
||||
}
|
||||
} else if (undoInfo.type == 2) {
|
||||
// 1=修改 2=添加 3=删除
|
||||
if (this.editorDom.length > undoInfo.index) {
|
||||
if (this.editorDom.length == undoInfo.index) {
|
||||
this.editorDom.push(dom);
|
||||
} else if (this.editorDom.length > undoInfo.index) {
|
||||
this.editorDom.splice(undoInfo.index, 0, dom);
|
||||
}
|
||||
if (this.editorDom.length == undoInfo.index) {
|
||||
this.editorDom.push(dom);
|
||||
} else if (this.editorDom.length > undoInfo.index) {
|
||||
this.editorDom.splice(undoInfo.index, 0, dom);
|
||||
}
|
||||
} else if (undoInfo.type == 3) {
|
||||
// 1=修改 2=添加 3=删除
|
||||
@@ -82,7 +86,7 @@ UndoRedo.prototype = {
|
||||
if (undoInfo.type == 1) {
|
||||
// 1=修改 2=添加 3=删除
|
||||
if (this.editorDom.length > undoInfo.index) {
|
||||
this.editorDom[undoInfo.index] = dom;
|
||||
vue.$set(this.editorDom, undoInfo.index, dom);
|
||||
}
|
||||
} else if (undoInfo.type == 2) {
|
||||
// 1=修改 2=添加 3=删除
|
||||
|
||||
Reference in New Issue
Block a user