实现一个简单的规则编辑器

0 阅读5分钟

功能介绍

左侧选择数据采集点位,右侧可以选择输入数值、运算符号等操作,配合构建出较为复杂的规则,本文主要讲规则配置部分,左侧选择点位部分比较简单,是一个正常el-table。

大致效果

image.png

思路(规则配置部分)

  1. 左侧使用一个contenteditable为true的div,用于展示可编辑状态,主要是需要光标,然后内部通过v-for去循环当前已经选择的点位、输入值、操作符。
  2. 右侧使用v-for循环展示按钮列表

遇到的问题

怎么获取当前光标位置

image.png

需要获取当前的光标位置,才能正常的新增和删除规则

点位展示的光标聚焦位置不对

image.png 点位使用的span展示,但是光标进入了点位信息内部,按期望应该显示在整个蓝色部分后面一点。而操作符号(+)不会出现这样的情况,因为它用的el-input加readonly属性实现,el-input的光标不会进入内部(通过数值输入框发现的)。

在数值输入框里键盘按下删除会把整个输入框删除

image.png

猜测是因为按下删除时,删除事件冒泡到外部,直接删除了整个输入框

问题处理

获取当前光标位置

获取光标有两种情况

  1. 点击了规则编辑框空白位置
  2. 点击了点位、值输入框、操作符

处理情况1

绑定整个框的点击事件,点击时通过document.getSelection()获得最新光标情况,getSelection会返回anchorNode节点,表示选区开始节点,这里还有个小细节,如图所示两个红色箭头处得到的anchorNode都是同一个元素,需要单独处理一下,我使用$event中的点击位置去做的判断,把第一个箭头处的那部分区域作为判断条件。 image.png

处理情况2

如果点击了点位、操作符,通过监听他们的click事件,使得就可以得到最新的光标位置,这种情况始终认为光标在点位、操作符框尾部。

点位展示的光标聚焦位置不对

根据问题处的图片可知,el-input类型的可以正常显示光标。所以,将点位展示改为输入框+realonly属性可以解决该问题。此时,又出现了一个小问题,el-input宽度是不会自适应的,而固定的太宽或太窄都显得比较奇怪,这里我通过文本个数计算了一个大致宽度(英文和符号这些算一半的font-size宽度)。

输入框错误问题删除

image.png 输入框内部按下删除键,默认会冒泡到div(属性contenteditable:true)的键盘事件,那个div绑定了键盘按下删除事件,用于删除输入框,所以阻止数值输入框keydown冒泡上去就可以了。

新的问题

点击后规则框后页面完全卡死问题

卡死.gif 如图,点击规则框之前,点击查询这些都是正常的,一旦点击规则框,页面直接卡死,cpu显示100%。浏览器是chrome(116.0.5845.97版)

完全卡死问题排查和处理

chrome性能面板

通过性能面板录制的信息来看,各项指标并不高,从箭头处开始完全卡死,下方堆栈信息、节点、监听器没有明显上升,箭头前面的上升部分,是进入弹窗时增加的,也还算正常。箭头处后面CPU状态占用100%,而且是系统占用,并非我的程序中占用,询问了ai,没问到太有用的信息,它建议我检查事件绑定、js是否死循环、添加防抖之类,但是经过检查,代码是没太大问题的。 image.png

注释和删除代码

我的页面并非一开始就这样了,而是在我通过ai加了些代码,自己又加了些代码,才导致一点击配置规则就卡死了的。所以,既然通过chrome面板分析不出问题,那就可以尝试去还原和注释代码去逐步发现问题,我把scss和js相关代码的都注释了。 image.png

发现问题

image.png 通过不断注释,发现问题出在:contenteditable="false"这个属性上的,本来我是为了防止点位和操作符内部被选择上,加的这个属性,删除后,页面恢复了正常。图片中,是我注释删除后简洁的代码。我分析的原因是,外层contenteditable为true,正常点击后会有一个光标落下,但是:contenteditable="false"使得el-input左右侧无法被设置光标(我全部都加了该属性),就导致光标无法正常落下,在浏览器内部处理时,出现了类似死循环的情况,导致页面完全卡死。

有趣的是,我在edge浏览器中也试了下,竟然完全不会卡死,并且光标能正常落下。所以,浏览器对于这个属性处理还是不一样的,我的chrome版本也不算太老,查了一下chrome116版本是2023年8月多发布的,这肯定不算是ie那种老古董。 image.png

写在最后

经过不断遇到和解决问题,规则编辑器趋近于正常,这个小小的编辑器虽然功能简单,但是也遇到了不少问题,不得不让人感叹更复杂的编辑器,如富文本编辑器以及vs code等开发工具,确实很厉害。