Selection API - daniel-qa/Vue GitHub Wiki

  • EX
// 將 range 縮小為只涵蓋第一個字元,避免 deleteContents 刪除整個選取
const firstCharRange = selection.getRangeAt(0).cloneRange() // 取得選取的第一個字
firstCharRange.collapse(true)                               // 把游標移到開始位置( Select start )
firstCharRange.setEnd(firstCharRange.startContainer, firstCharRange.startOffset + 1) // 把選取範圍的「結尾」往後推一個位置
firstCharRange._firstChar = firstChar  // 把字的值,暫存起來
savedRange = firstCharRange   // 把目前的 Range「指標」存起來,之後還能回到同一個選取位置
  • collapse(true) 的意思是把「選取範圍」縮成一個點。 #

想像你在 Word 裡用滑鼠拖曳選了一段文字:

你好世界,這是測試文字。
    ^^^^^^^^^^^^
你選了這一段

這個選取範圍有起點和終點。

collapse(true) 就是說:「把這個選取範圍縮成只剩起點那個游標位置」

你好世界,這是測試文字。
    |
    游標在這,沒有選任何東西

true = 縮到起點

false = 縮到終點


瀏覽器底層 DOM APISelection API

取得使用者目前選取的內容

包含:

游標位置
反白範圍
選取方向
  • 取得 Selection
const selection = window.getSelection()

常用屬性

selection.anchorNode
selection.anchorOffset

selection.focusNode
selection.focusOffset

  • 補充說明

firstCharRange._firstChar = firstChar 的作用

核心一句話

在 Range 物件上「額外掛一個自訂資料」

用來保存第一個字元

這是什麼技術?

叫做:

Monkey Patch(猴子補丁)

或更精確:

Dynamic property injection

本質

Range 原本只有:

startContainer
startOffset
endContainer
endOffset

但你加了:

_firstChar

等於:

偷偷幫瀏覽器原生物件加欄位

作用

  1. 記住當下操作的字
_firstChar = firstChar

例如:

使用者選到「少」

你就存:

range._firstChar = "少"
  1. 後續流程使用

例如:

onPickPhonic()

可以直接取:

savedRange._firstChar

不用再從 DOM 拿一次。

  1. 保留語意狀態

Range 本身只管:

位置

不管:

內容語意

你補的是:

「這次操作的字是什麼」

為什麼要這樣做?

因為 Selection / Range:

只描述位置,不描述內容語意

所以你需要自己補一層:

業務資料