你可能不知道的JS關於選中文本區域的操做

聲明:今天所分享的內容,均可以直接在控制檯演示。
先來思考幾個問題。
1.我在一個頁面中隨意點了一下,沒有留下任何痕跡。你能捕捉到我剛纔點的是哪一個節點,以及鼠標的落腳點在哪兩個字之間嗎(點擊圖片是無效的,本文只討論文本的狀況)?
2.如何作到點擊任意節點,選中而且複製任意一段文字呢?
3.如何用腳本控制你用鼠標選中的區域呢(控制所選範圍的大小,起始位置)?node

上面三個問題,你能答出幾道?這幾個問題都是跟當前選擇區域相關的知識點,這裏咱們合併在一塊兒講一下。先普及一些關於文本選擇範圍的基礎知識。主要涉及到兩個對象,Selection和Range。能夠理解成Selection由Range組成,Selection表示當前頁面中鼠標選中的區域對象,能夠用window.getSelection()來獲取Selection對象,你能夠用鼠標在當前頁選取一個範圍,而後打開控制檯,輸入window.getSelection()便可打印出Selection對象。能夠調用selection的toString方法,結果就會打印出咱們選擇的文本內容。
let selection = window.getSelection();
console.log(selection.toString());

selection有一個rangeCount屬性,用來判斷當前選擇區域有多少個range,重點來了:當進入一個網頁,或者刷新當前頁以後,若是你沒有點擊過任何地方,則selection的rangeCount值爲0,一旦你點擊過任何地方,此時rangCount的值就變成了1(此時你就能夠打開控制檯在控制檯測試了)。因此這就能夠用來判斷當前頁有沒有被點擊過。測試

let selection = window.getSelection();
if (selection.rangeCount == 0) {
  console.log('當前頁面尚未被點擊過');
} else {
  console.log('當前頁面已經被點擊過');
// 獲取當前selection中的range。(在網頁中經過手動去選擇範圍只能有一個range。用腳本能夠實現selection中包含多個range的狀況。)
  let range = selection.getRangeAt(0); 
}

當咱們知道當前頁面被點擊過以後,就能夠來判斷是哪一個節點被點擊了。點擊了哪兩個字的中間。此時就會用到幾個range的屬性,分別是startContainer,endContainer,startOffset,endOffset.先來看控制檯打印出來的幾個range的屬性。
圖片描述spa

collapsed:表示當前range範圍是不是閉合的。true則表示當前range範圍的起始和結束是同一個位置。其實就是當前頁面上沒有被選擇的範圍。也能夠認爲當前選擇範圍是一個點。
commonAncestorContainer: 表示共同的祖先節點。若是當前選擇範圍是跨節點的,即個人開始點是在上一個div,結束點在他的兄弟節點div中。那此時commonAncestorContainer就表示他倆的父節點(最近的公共祖先節點)。若是開始點和結束點在同一個div中,則此屬性的值指向當前div。
startContainer/endContainer: 範圍起始點和結束點所在的節點中。
startOffset/endOffset: 範圍起始點和結束點在當前container中的偏移量,即在startContainer(或endContainer)中,起始點(或結束點)前面有多少個字。

結合上面的四個屬性,咱們就能輕易的找到剛纔點擊的哪一個位置,(若是隻是點擊一下的話,collapsed值爲true,startContainer和endContainer相同,startOffset和endOffset相等)到這裏,咱們開篇提到的第一個問題就解決了。
第一個問題理解了以後,後面的兩個就變的很簡單了。咱們先來看第三個,只是用range的幾個方法。設置一下range的邊界值便可。code

setStartAfter()
setStartBefore()
setEndAfter()
setEndBefore()
// 上面這四個方法是設置range範圍的起始和結束位置的,參數傳入節點便可。
setStart()
setEnd()
// 上面這兩個方法有兩個參數,第一個傳入節點,第二個傳入偏移量,即從當前節點的第幾個字開始。注意:這裏的節點指的是文本節點(nodeType是3的text節點)。

下面看第二個問題。首先選中一段文字,而後執行復制命令。對象

// 選中一段文字
let div = document.getElementById('div');
let selection = window.getSelection();
let range = document.createRange();
range.selectNode(div);
selection.removeAllRanges();
selection.addRange(range);
// 執行復制命令
document.execCommand('copy', false, null);

這裏用到了一個很好用的方法,document.execCommand(),感興趣的朋友本身下來查一下吧。
無論你是小哥哥仍是小姐姐,以爲東西不錯?給個贊再走吧!blog

相關文章
相關標籤/搜索