range 標準化之獲取
range 用來表示用戶的選擇區(qū)域,這塊選擇區(qū)域由兩個邊界位置界定,而位置則由其容器以及偏移量構(gòu)成,稱作 container 與 offset .如下是一個簡單的位置示例:
<p><span>文字</span>^<span>文字</span></p>
其中 ^ 表示一個位置,則 container 為父節(jié)點 p,offset即為相對于父節(jié)點的偏移量為1。需要注意的是當container為元素節(jié)點時,其偏移量單元為節(jié)點,即從容器的第一個子節(jié)點到當前位置處所經(jīng)歷的子節(jié)點數(shù)。
相應(yīng)的,container也可以是文字節(jié)點,這時container 為 textnode ,而offset則為從該textnode到當前位置所經(jīng)歷的 utf-16 字符個數(shù)(意味著,中文和英文計數(shù)一樣,不是字節(jié)計數(shù))。如
<p><span>文字</span><span>01234^567</span></p>
上例中 container 為 "01234567" 這個文字節(jié)點,而offset 則是從該文字節(jié)點第一個字符到當前位置所經(jīng)歷的字符個數(shù)即5.
ie range
簡要介紹一下,具體請查閱 msdn
ie range 沒有清晰的容器與偏移量的概念,但是基本思想和 w3c range 一樣,具備同等的表達能力,分為 textrange 與 controlrange,包含一系列的方法。
textrange 不是從字面意義上的單純文本,而是表示用戶的選擇區(qū)域內(nèi)容(可用其htmlText獲取完整內(nèi)容),其操作方式大多是以文字為單元而不是 dom 樹節(jié)點。
controlrange 字面意思表示獲取選擇 控件 ,實際是有些元素(div,img,object...)處于可編輯狀態(tài)時,經(jīng)單擊可將整個元素選中。
ie 標準化之獲取
從上面介紹可見,w3c 的range更規(guī)范,更清晰,其 container 與 offset 的概念更直觀,當我們需要對range關(guān)聯(lián)dom節(jié)點進行操作時,無疑 container ,offset是必不可少的,而 ie range 則沒有顯示的提供獲取這兩個關(guān)鍵變量的方法, 前面說過 ie range 其實具備 w3c range 等價的功能,那么就可以結(jié)合其提供的一系列方法推導(dǎo)出這兩個變量。
范圍對象獲?。?
范圍對象有兩種獲取方式:
1.從當前選擇區(qū)域獲得 range ,可調(diào)用
document.selection.createRange()
方法根據(jù)目前選擇,返回 TextRange 或 ControlRange 實例。
2.從元素創(chuàng)建 range ,可調(diào)用
oControlRange = object.createControlRange()
Js代碼
oTextRange = object.createTextRange()
前一種 之能在 body,element上調(diào)用,而后一種 可在大多數(shù)元素上調(diào)用。調(diào)用后則該范圍完全覆蓋調(diào)用元素。相當于 moveToElementText 。
textrange 標準化:首先介紹下用到的幾個方法:
collapse :根據(jù)參數(shù)將結(jié)束位置重合到開始位置(true)或開始位置重合到結(jié)束位置(false)。
parentElement :獲取包圍選擇區(qū)域的元素節(jié)點,如下例調(diào)用后得到span節(jié)點。
<span>文^字</span>
moveToElementText (Node a) :將選擇區(qū)域變更為 a ,起始位置為 a 的前后,如作用到如下 span 節(jié)點后:
^<span>文字</span>^
range1.compareEndPoints('XxToYy',range2) :xx,yy 可以為 Start 或 End,取 range1 的 xx 位置和 range2 的 yy 位置比較,根據(jù)前后順序返回-1,1,0表示重合。
range1.setEndPoint("XxToYy",range2) :xx,yy 可以為 Start 或 End,將range1的xx位置設(shè)為range2的yy位置。
轉(zhuǎn)化:
有了上面的5個方法就可以開始我們的標準化第一步:獲取位置,首先給出操作例子:
(綠塊表示文字節(jié)點,注意:正常手工編寫頁面情況下不會出現(xiàn)兩個相鄰的文字節(jié)點,這里使用 splitText 強制分離 )
當我們將選擇區(qū)域collapse后,可能有上述四個位置:1,2,3,4,其中 1,4 相鄰元素節(jié)點最簡單:
1,4位置 標準化:
1.根據(jù) parentElement 得到包含位置的節(jié)點 p ,即為該位置的container
2.對container的所有元素子節(jié)點,一一驗證是否和已知位置相鄰,驗證方法即為:通過 moveToElementText 新建range包圍子節(jié)點,再通過 compareEndPoints 比較是否新建 range 的前后位置是否和當前位置重合:
range = range.duplicate();
range.collapse(start);
var parent = range.parentElement(),
siblings = parent.childNodes;
for (var i = 0; i < siblings.length; i++) {
var child = siblings[i];
if (child.nodeType == 1) {
var tr = range.duplicate();
tr.moveToElementText(child);
//子元素節(jié)點開始位置比較
var comparisonStart = tr.compareEndPoints('StartToStart', range),
//子元素節(jié)點結(jié)束位置比較
comparisonEnd = tr.compareEndPoints('EndToStart', range);
//開頭已經(jīng)在當前位置后面,沒必要繼續(xù)比了
if (comparisonStart > 0) break;
else if (!comparisonStart || comparisonEnd == 1 && comparisonStart == -1) return {
container: parent,
offset: i
};
else if (!comparisonEnd) return {
container: parent,
offset: i + 1
};
}
}
2,3位置 標準化:
2 表示位置在兩個文字節(jié)點之間,container為 p ,由于moveToElementText 無法作用文字節(jié)點,則只能另想他法。
3 表示位置處于文本節(jié)點中間,此時 container 為文本節(jié)點,而 offset 則要數(shù)字符數(shù)了。
1.當?shù)竭_ 1 位置時,停止。
2.新建range ra,開始位置為 1,結(jié)束位置為2或3,取得 ra的所有字符數(shù) ra_textlength,對從位置1開始往右的每個文字節(jié)點,從 ra_textlength 中減去其長度(data.length),當 ra_textlength 為0時,代表當前位置為2,而當前經(jīng)過的文字節(jié)點數(shù)目即為offset。
當 ra_textlength 為負數(shù)時,表示當前位置為3, 當前的文字節(jié)點即為位置3 的container,ra_textlength 的上一個值則是offset。
示例:
<p id="test"><strong>粗體</strong>普通|文字<i>斜體</i></p>
<script>
document.getElementById("test").childNodes[1].splitText(2);
</script>
controlrange 標準化
controlrange 就很簡單了,由 item(index) 方法得到選擇元素,結(jié)合其parentNode 就可以得到標準化表示了。
PS : 關(guān)于輸入框的范圍讀取
由于規(guī)范規(guī)定輸入框的選擇區(qū)域和頁面選擇區(qū)域是分離的,輸入框的選擇區(qū)域有不同的獲取方式 (IE 基本相同)。
相關(guān)文章
使用Three.js?實現(xiàn)虎年春節(jié)3D創(chuàng)意頁面
虎年春節(jié)將至,本文使用?React?+?Three.js技術(shù)棧,實現(xiàn)趣味?3D創(chuàng)意頁面,主要包括:ShadowMaterial、?MeshPhongMaterial等基本材質(zhì)的使用、使用?LoadingManager展示模型加載進度、OrbitControls`的緩動動畫、TWEEN簡單補間動畫效果等,感興趣的朋友一起看看吧2022-01-01基于Bootstrap實現(xiàn)下拉菜單項和表單導(dǎo)航條(兩個菜單項,一個下拉菜單和登錄表單導(dǎo)航條)
這篇文章主要介紹了基于Bootstrap實現(xiàn)下拉菜單項和表單導(dǎo)航條(兩個菜單項,一個下拉菜單和登錄表單導(dǎo)航條)的相關(guān)資料,需要的朋友可以參考下2016-07-07