如何使用原生 JS 實現一個文字劃線功能

羅輯思維前端開發團隊發表於2018-05-25

0x0. 效果

先上效果圖:

如何使用原生 JS 實現一個文字劃線功能

0x1. 起因

得到 APP 中有個文稿模組,這部分是內嵌的前端開發的 Web 頁面,支援在客戶端和微信中訪問,其中有一個稱為劃線筆記的功能,就是長按文字之後,對選中的文字做標記,這是背景。

在一次需求迭代過程中,產品對劃線筆記的功能提出了一些問題,比如為什麼 iOS 和 Android 的樣式不統一(用的是系統原生的長按選中),是不是可以實現單擊就可以選中文字,是不是可以自定義樣式,是不是可以正反選……

聽到這裡我的內心是這樣的

5ae91d7ecb3a9

本著跟產品友好相處的原則,我當即表示這個些需求很棒,我需要認真想一下怎麼拒絕

0x2. 分析

當然,想法歸想法,做還是要想辦法做的

5ae91ee7a005f

從產品的需求看,只有自己模擬一個系統的長按選中才可以滿足產品現階段及將來可能潛在的需求。如果模擬一個長按選中,大概需要解決這麼幾個問題:

  • 需要禁用系統的長按選擇文字
  • 需要獲取到點選字元的確切位置
  • 需要能夠模擬選中時的矩形背景

0x3. 實現

針對剛才的分析,大概可以這樣實現:

第一點,新增 user-select: none 的樣式,這樣可以直接禁用系統的文字選擇; 第二點,能夠間接或者直接獲取字元位置的 dom API, 大概只有間接的通過 Range.getClientRects()

第三點,最初構思有兩個方案,一個是直接在文字中插入標籤,這樣勢必會改變整個 dom 的結構,對後續的標記造成影響,於是採用第二個方案,直接加一個 svg 層,通過 svg 的多邊形和矩形來繪製

最後,具體實現見 github.com/luojilab/ea…,我們已經把這個方案開源出來了

5ae92213e23de

這個方案有以下有點:

  • 自定義選擇樣式
  • 點選選中當前句子
  • 長按選中當前句子
  • 正向反向選擇
  • 高亮標記選中的文字
  • ......

有需要的小夥伴歡迎 star, iusse, pr 走起。

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

相關文章