W3C

Web 中文兴趣组会议

2022年9月6日

题目:实现富文本内容选中的讨论

讲者:蔡寰宇(积木文档)[演示文稿]

现场纪要

蔡寰宇:

大家好,我是来自积木文档的蔡寰宇。刚才听完云澹的分享,深受感触,发现大家都是在Selection上遇到了比较大的问题。其实今天我不算分享,主要是和大家探讨一下Selection的问题。和云澹讲的基本差不多,我们的几个case比较简单,所以我可以比较快的带大家一起看一下。

首先,第一个问题是关于文本Selection的样式问题,首先是可以通过文本的CSS改变样式,但它的支持度比较低,比如的需求是需要控制选中区高度,它是无法让我们修改Selection的高度。我们的做法是通过监听浏览器Selection的变化,自己实现了Text Selection,实现了自定义的Text Selection之后,我们会对选定的文本确定文本样式。

有一些特殊的做法是文本有很多是inline元素,无法拓展高度,想拓展高度就比较另辟蹊径,我们的做法是用padding,不同的padding行高和字体大小不一样,我们是通过CSS变量的方式获取,把这个高度撑起来。这是第一个case。

第二个case,因为是富文本的编辑器,我们都会在文本元素和非文本元素之间跨越交互的问题,如果用户在选中文本的时候,跨越了非文本的元素,默认API的Focus Node,Focus Node会直接跨越所有的非文本元素,聚焦到下一个文本节点,为了避免这个问题,我们依然会监听Selection的变化,我们自己创建了Node Selection和非文本的Selection。在Selection变化过程中,我们会看,如果用户选中的Selection末尾是连续的非文本元素,这时候它的Focus Node已经全部越过去,到下一个非文本节点,为了避免这样的情况,我们的处理方式就是把末尾选定的非文本元素全部去除掉,为了保证用户在做文本选择上的连贯性。

虽然说,可能也有一些问题,但是,针对文本选择的行为来说,它是更符合预期的。

下一个case是通过鼠标拖拽区域框选Focus Node元素,这个本身Selection不支持,我们需要自己实现。我们的实现方式是通过鼠标的mousedown、mouseup、mousemove事件来绘制拖拽区域,计算区域内的哪些node和元素,自己创建Selection。

因为这个事情是我们自己实现,就需要考虑很多边界问题。比如说当鼠标移出了可监听的范围,比如移出了浏览器界面,移到外面之后释放了鼠标,我们就无法监听到这个事件,还有比如说mousedown在文本中触发的框选,我们默认它是文本框选,就不会触发框选元素的行为。如果是在非文本区域点击的话,我们会确定为框选元素的行为。如果又是在文本外发生mouse down的行为,都要进行处理,还有这些是拖拽行为,又要避免了Selection冲突,就需要有很多边界问题需要处理。

这就是我们做文档编辑器时候关于Selection遇到的几个比较难受的问题。

就可以看出现在Selection在浏览器上支持不是特别友好,我们自己以及语雀他们都需要自己去实现。可以看到自己实现的过程中,是要费很多力气,总会有一些比较蹩脚的地方。所以,我们比较希望能看到有更强大的Selection功能提供出来,不仅仅是针对文本的能力,应该还需要针对块级元素的能力。


返回[会议总结页面]获取其他话题的会议纪要。

若您对上述内容有任何疑问或需进一步协助,请联系:会议主办方 W3C 北航总部 <team-beihang-events@w3.org>。