2年前有个中台文档产品有个划词评论的功能,那时候还写了篇文章介绍了相关的技术实现,参见:"划词评论与Range开发若干经验分享"
一直运行的好好的。
突然,就在最近,老板提了一嘴,这手机上怎么没法划词评论。
好了,需求就来了。
当时手机上内置的复制、翻译等tips等与划词评论小按钮会有冲突,以及开发成本等原因(台式机模拟touch长按有些麻烦),就没做。
简单研究了下,事件是通用的,就是selectionchange
事件。
一、关于selectionchange事件
根据我的测试,selectionchange
发生在选区范围发生变化的时候,假如你拖拽选区范围的"棒棒子"改变文本的选中范围,此事件是不断触发的。
使用示意:
尝试选中这段文字:《HTML并不简单》是目前市面上...
<p id="result"></p>
document.addEventListener('selectionchange', function () {
const selection = document.getSelection();
result.textContent = selection.toString().trim();
});
此时,我们选中任何选区,p#result
元素就会显示选中的文本内容,截图示意:
这个demo手机也可以体验,您可以狠狠地点击这里:JS selectionchange事件体验demo
二、选区执行时机的区别
在PC端和移动端,由于选区消失的时机是有区别的,因此,在交互处理上会有所不同。
例如,我们选中选区,悬浮一个按钮,点击此按钮,使用surroundContents()
API包裹选中的文字,在PC端,我们可以给按钮使用click事件。
因为在PC端(Android好像也是),文字选区的消失是在click事件之后。
但是在iOS端,不知道是不是客户端APP的问题,选区的消失在click事件之前。
因此,在实际处理的时候,按钮的点击事件需要使用touchstart处理才行。
这是其中的一个执行细节,希望可以帮助到做类似需求的同行。
三、selectionchange绑定元素和事件对象
selectionchange
事件只能绑定在document上,以及原生的可输入元素上,是不能绑定在普通元素之上的。
例如,下面的JS代码是不会触发任何行为执行的:
document.body.addEventListener('selectionchange', function () {
// 不会触发执行
});
但如果是输入框,例如<input>
或者<textarea>
则是没问题的,例如:
input.addEventListener('selectionchange', function () {
// 可以执行
});
那如果是一个普通的元素,但是设置了contenteditable="true"
,变得可输入,那还支持'selectionchange'
吗?
根据我的测试,是不支持的。
事件对象
相比传统的事件,selectionchange
事件的event对象会有很多缺失,例如坐标位置等信息,以Chrome浏览器举例,支持的属性见如下截图。
因此,如果希望元素相对于选区定位,event对象是帮不上任何忙的,还是需要使用选区本身的API才行,具体见本文一开始提到的那篇文章。
四、其他就没有什么了
其他就没什么了,比较冷门的一个JS DOM事件API,但我使用下来,还挺好用的,比较稳健,其兼容性也不错,如下截图所示:
希望可以帮到诸位道友,哎呀,嘴瓢了,同行,行友,看制作精良的韩跑跑傻屌漫看得有些走火入魔了,哈哈哈。
(本篇完)