1.实现一个怎样的需求?

今早接到的需求,新建会议时可以书写会议议程,书写议程时可以艾特对应的人员,并自动将所艾特的人员添加进会议中。
需求难点在哪?
1.如何实现一个带img的输入编辑框 (几乎没得选择,输入框实现只有两种思路,1.input 2.contenteditable="true")
2.如何监听@信息?
3.如何知道@后以什么分割?eg:(嘻嘻嘻@张三丰,你好帅阿)如何知道输入的是张三丰
4.选择后如何插入
2.实现思路
至于第二点的思考,本来考虑的时候监听键盘事件,然后发现因为需求上可以有多条议程,监听键盘事件无法知道@是在
哪一行的标志。所以使用了@input事件去监听文字更改。当监听到@后面有值时就去做拉对应的人员接口。
然而悲伤的是,我发现无法在中间插入时文字时实现艾特。
3.解决方案
this.sel = window.getSelection()
this.range = window.getSelection().getRangeAt(0);
引入一个概念
光标:我们对应的光标其实是一个矩形,并不是一根竖线!!!。
这个时候其实问题3就解决了,我们可以拿到对应光标区间的文字。
window.getSelection().getRangeAt(0).commonAncestorContainer.data
然后通过range.endOffset去做一个截取,就是我们输入要搜索的值。
问题4:
我们选择了对应的人员生成图片后如何插入到当前位置呢,首先我们需要清除对应的内容,即@张xx.
我们需要将对应的range区域更改
this.range.setStart(this.sel.anchorNode || p.firstChild, this.startIndex)
this.range.setEnd(this.sel.anchorNode || p.firstChild, this.range.endOffset);
然后去除内容
this.range.deleteContents()
创建node(这一步要在去除前)
const node = this.range.createContextualFragment(`<img class="person-img" data-id=${item.oid} data-name=${item.name} src=${dataUrl} />`);
插入
this.range.insertNode(node);
折叠选择区域当末端
this.range.collapse(false)
然后去除所有选择区域,再增加区域
this.sel.removeAllRanges()
this.sel.addRange(this.range);