如何使用原生 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 走起。

文章首發於羅輯思惟前端知乎專欄,歡迎關注。

相關文章
相關標籤/搜索