浏览器默认有这样一个行为:当用户双击一段文本时,会选中单词(中文有分词处理),当三击时,会选中整段文本。
这个「选中整段文本」的行为所产生的浏览器选区 Selection 对象上,extendNode、focusNode 是当前块级文本的下一行的节点。
而如果用户通过手动拖拽行为,从段落开头框选到段落结尾,这时产生的选区对象上,上述的两个字段是当前块级文本的末尾节点。
对比这两种操作,用户看到的选区是一样的,实际生成的选区对象却是不同的,从编辑器框架的角度看,前者的 range 似乎比后者多了 1。
这就会造成很多问题,如果在此时进行插入带格式文本的操作,就会有意料之外的效果。
那么如何解决这个问题?
- Quill 没有处理这种情况,两种操作下获取到选区的长度相差 1。所以我遇到了 bug,也才有了本文的记录。
- ProseMirror 实现了三次点击的行为监听,在其中拦截了,参考 ProseMirror 源码。
- Slate 将这种选区称为「hanging range」,并对它进行一次
unhang的格式化处理,在其中重新计算了选区结尾节点,参考 Slate 源码。关于它,也有一些比较有趣的社区讨论。