找回密码
 快速注册
搜索
查看: 49|回复: 4

Discuz编辑器撤销键

[复制链接]

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2022-8-7 21:42 |阅读模式
比如输入abcd,然后按backspace(把d删了),再按编辑器右上角的撤销按钮,竟然没有把d恢复,而是把整个abc都删了

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

kuing 发表于 2022-8-7 22:04
还真是😅
不过我从来没用过那个按钮……
纯粹多余,用 Ctrl+Z 不就好了……

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

 楼主| hbghlyj 发表于 2022-8-7 23:48
kuing 发表于 2022-8-7 15:04
还真是😅
不过我从来没用过那个按钮……
纯粹多余,用 Ctrl+Z 不就好了…… ...


我这边“插入链接”无法用Ctrl+Z撤销, 但是可以用那个按钮撤销

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

 楼主| hbghlyj 发表于 2022-8-9 00:00
kuing 发表于 2022-8-7 15:04
还真是😅
不过我从来没用过那个按钮……
纯粹多余,用 Ctrl+Z 不就好了…… ...


好像就是专门用于撤销“由编辑工具引起的更改”而非“文本操作的更改”
editor.js中的function discuzcode(cmd, arg)函数
else if(cmd == 'undo') {
                addSnapshot(getEditorContents());
                moveCursor(-1);
                if((str = getSnapshot()) !== false) {
                        if(wysiwyg) {
                                editdoc.body.innerHTML = str;
                        } else {
                                editdoc.value = str;
                        }
                }
        }
else if(cmd == 'redo') {
                moveCursor(1);
                if((str = getSnapshot()) !== false) {
                        if(wysiwyg) {
                                editdoc.body.innerHTML = str;
                        } else {
                                editdoc.value = str;
                        }
                }
        }

有一个全局变量stack,是一个array,用来存储编辑历史.
在1656行getSnapshot的定义:
function getSnapshot() {
        if(!isUndefined(stack[cursor]) && stack[cursor] != null) {
                return stack[cursor];
        } else {
                return false;
        }
}

那个cursor是当前状态在编辑历史中的序号,如果没有撤销过的话,getSnapshot会取出stack的最后一个;如果撤销过的话,getSnapshot会取出stack的当前状态的前一个编辑状态.
在1643行addSnapshot的定义:
function addSnapshot(str) {
        if(stack[cursor] == str) {
                return;
        } else {
                cursor++;
                stack[cursor] = str;

                if(!isUndefined(stack[cursor + 1])) {
                        stack[cursor + 1] = null;
                }
        }
}

可见addSnapshot的效果是,拿str和当前状态stack[cursor]对比如果没变,就结束(这时可以重做(redo)回去了);如果变了,就把当前状态更新,并把后面的都清空(这就无法重做(redo)回去了).

再来看function discuzcode(cmd, arg)函数的开头:
if(cmd != 'redo') {
                addSnapshot(getEditorContents());
        }

所以加粗,加下划线,插入链接⋯这些工具在作用之前,会先调用addSnapshot,把“工具作用之前”的状态保存到stack[cursor]


例如输入111
这时stack是空的 Array(3) [ "" ]
这时cursor是0
然后选中最后一个1,再使用下划线工具,变成11[u]1[/u]
这时stack变成 Array(3) [ "", "111", "11[u]1[/u]" ]
这时cursor是2 (当前状态是stack的第3个状态,即最后1个状态)
按下撤销(undo)工具,
这时stack不变
这时cursor是2 (当前状态是stack的第2个状态)
按下重做(redo)工具,
这时stack不变
这时cursor是3 (当前状态是stack的第3个状态)
按下撤销(undo)工具,再插入一个链接,变成11[u]1[/u][url=1]www[/url]
这时stack不变
这时cursor不变
再插入一个链接,变成11[u]1[/u][url=1]www[/url][url=1]www[/url]
这时stack变成Array(4) [ "", "111", "11[u]1[/u]", "11[u]1[/u][url=1]www[/url]" ]
这时cursor不变

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

kuing 发表于 2022-8-9 14:19
hbghlyj 发表于 2022-8-9 00:00
好像就是专门用于撤销“由编辑工具引起的更改”而非“文本操作的更改”
见editor.js中的function discuzc ...


虽然看8懂,但看起来好腻害嘀样纸😃

手机版|悠闲数学娱乐论坛(第3版)

GMT+8, 2025-3-4 15:28

Powered by Discuz!

× 快速回复 返回顶部 返回列表