如何使用原生 JS 实现一个文本划线功能

0x0. 效果

先上效果图:前端

0x1. 原由

获得 APP 中有个文稿模块,这部分是内嵌的前端开发的 Web 页面,支持在客户端和微信中访问,其中有一个称为划线笔记的功能,就是长按文字以后,对选中的文字作标记,这是背景。git

在一次需求迭代过程当中,产品对划线笔记的功能提出了一些问题,好比为何 iOS 和 Android 的样式不统一(用的是系统原生的长按选中),是否是能够实现单击就能够选中文字,是否是能够自定义样式,是否是能够正反选……github

听到这里个人心里是这样的微信

5ae91d7ecb3a9

本着跟产品友好相处的原则,我立即表示这个些需求很棒,我须要认真想一下怎么拒绝dom

0x2. 分析

固然,想法归想法,作仍是要想办法作的svg

5ae91ee7a005f

从产品的需求看,只有本身模拟一个系统的长按选中才能够知足产品现阶段及未来可能潜在的需求。若是模拟一个长按选中,大概须要解决这么几个问题:3d

  • 须要禁用系统的长按选择文字
  • 须要获取到点击字符的确切位置
  • 须要可以模拟选中时的矩形背景

0x3. 实现

针对刚才的分析,大概能够这样实现:code

第一点,添加 user-select: none 的样式,这样能够直接禁用系统的文字选择; 第二点,可以间接或者直接获取字符位置的 dom API, 大概只有间接的经过 Range.getClientRects()cdn

第三点,最初构思有两个方案,一个是直接在文字中插入标签,这样势必会改变整个 dom 的结构,对后续的标记形成影响,因而采用第二个方案,直接加一个 svg 层,经过 svg 的多边形和矩形来绘制blog

最后,具体实现见 github.com/luojilab/ea…,咱们已经把这个方案开源出来了

5ae92213e23de

这个方案有如下有点:

  • 自定义选择样式
  • 点击选中当前句子
  • 长按选中当前句子
  • 正向反向选择
  • 高亮标记选中的文字
  • ......

有须要的小伙伴欢迎 star, iusse, pr 走起。

文章首发于罗辑思惟前端知乎专栏,欢迎关注。

相关文章
相关标签/搜索