您好,登錄后才能下訂單哦!
這篇文章主要介紹Javascript中DOM范圍的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
創(chuàng)建范圍
Document類型中定義了createRange()
方法。在兼容DOM的瀏覽器中,這個方法屬于document對象。使用hasFeature()
或者直接檢測該方法,都可以確定瀏覽器是否支持范圍
[注意]IE8-瀏覽器不支持
var supportsRange = document.implementation.hasFeature("Range", "2.0"); var alsoSupportsRange =(typeof document.createRange == "function");
如果瀏覽器支持范圍,那么就可以使用createRange()
來創(chuàng)建DOM范圍,如下所示
var range = document.createRange();
與節(jié)點類似,新創(chuàng)建的范圍也直接與創(chuàng)建它的文檔關聯(lián)在一起,不能用于其他文檔。創(chuàng)建了范圍之后,接下來就可以使用它在后臺選擇文檔中的特定部分。而創(chuàng)建范圍并設置了其位置之后,還可以針對范圍的內(nèi)容執(zhí)行很多種操作,從而實現(xiàn)對底層DOM樹的更精細的控制
每個范圍由一個Range類型的實例表示,這個實例擁有很多屬性和方法。
下列屬性提供了當前范圍在文檔中的位置信息
startContainer:包含范圍起點的節(jié)點(即選區(qū)中第一個節(jié)點的父節(jié)點)
startoffset:范圍在startContainer中起點的偏移量。如果startContainer是文本節(jié)點、注釋節(jié)點或CDATA節(jié)點,那么startoffset就是范圍起點之前跳過的字符數(shù)量。否則,startoffset就是范圍中第一個子節(jié)點的索引
endContainer:包含范圍終點的節(jié)點(即選區(qū)中最后一個節(jié)點的父節(jié)點)
endOffset:范圍在endContainer中終點的偏移量(與startoffset遵循相同的取值規(guī)則)
commonAncestorContainer:startContainer和endContainer共同的祖先節(jié)點在文檔樹中位置最深的那個
在把范圍放到文檔中特定的位置時,這些屬性都會被賦值
簡單選擇
要使用范圍來選擇文檔中的一部分,最簡單的方式就是使用selectNode()
或selectNodeContents()
。這兩個方法都接受一個參數(shù),即一個DOM節(jié)點,然后使用該節(jié)點中的信息來填充范圍。其中,selectNode()
方法選擇整個節(jié)點,包括其子節(jié)點;而selectNodeContents()
方法則只選擇節(jié)點的子節(jié)點
<!DOCTYPE html> <html> <body> <p id="p1"><b>Hello</b> world!</p> </body> </html>
我們可以使用下列代碼來創(chuàng)建范圍
var range1 = document.createRange(); var range2 = document.createRange(); var p1 = document.getElementById("p1"); //Range {startContainer: body, startOffset: 1, endContainer: body, endOffset: 2, collapsed: false…} range1.selectNode(p1); //Range {startContainer: p#p1, startOffset: 0, endContainer: p#p1, endOffset: 2, collapsed: false…} range2.selectNodeContents(p1);
這里創(chuàng)建的兩個范圍包含文檔中不同的部分:rangl包含<p>元素及其所有子元素,而rang2包含<b>元素、文本節(jié)點"Hello"和文本節(jié)點"world!"
在調(diào)用selectNode()
時,startContainer、endContainer和commonAncestorContainer都等于傳入節(jié)點的父節(jié)點,也就是這個例子中的document.body
。而startoffset屬性等于給定節(jié)點在其父節(jié)點的childNodes集合中的索引(在這個例子中是1——因為兼容DOM的瀏覽器將空格算作一個文本節(jié)點),endOffset等于startoffset加1(因為只選擇了一個節(jié)點)
在調(diào)用selectNodeContents()
時,startContainer、endContainer和commonAncestorContainer等于傳入的節(jié)點,即這個例子中的<p>元素。而startoffset屬性始終等于0,因為范圍從給定節(jié)點的第一個子節(jié)點開始。最后,endOffset等于子節(jié)點的數(shù)量(node.childNodes.length
),在這個例子中是2
此外,為了更精細地控制將哪些節(jié)點包含在范圍中,還可以使用下列方法
setStartBefore(refNode)
:將范圍的起點設置在refNode之前,因此refNode也就是范圍選區(qū)中的第一個子節(jié)點。同時會將startContainer屬性設置為refNode.parentNode,將startoffset屬性設置為refNode在其父節(jié)點的childNodes集合中的索引
setStartAfter(refNode)
:將范圍的起點設置在refNode之后,因此refNode也就不在范圍之內(nèi)了,其下一個同輩節(jié)點才是范圍選區(qū)中的第一個子節(jié)點。同時會將startContainer屬性設置為refNode.parentNode,將startoffset屬性設置為refNode在其父節(jié)點的childNodes集合中的索引加1
setEndBefore(refNode)
:將范圍的終點設置在refNode之前,因此refNode也就不在范圍之內(nèi)了,其上一個同輩節(jié)點才是范圍選區(qū)中的最后一個子節(jié)點。同時會將endContainer屬性設置為refNode.parentNode,將endOffset屬性設置為refNode在其父節(jié)點的childNodes集合中的索引
setEndAfter(refNode)
:將范圍的終點設置在refNode之后,因此refNode也就是范圍選區(qū)中的最后一個子節(jié)點。同時會將endContainer屬性設置為refNode.parentNode,將endOffset屬性設置為refNode在其父節(jié)點的childNodes集合中的索引加1
調(diào)用這些方法時,所有屬性會自動設置好。不過,要想創(chuàng)建復雜的范圍選區(qū),也可以直接指定這些屬性的值
復雜選擇
要創(chuàng)建復雜的范圍就得使用setStart()
和setEnd()
方法。這兩個方法都接受兩個參數(shù):一個參照節(jié)點和一個偏移量值。對setStart()
來說,參照節(jié)點會變成startContainer。而偏移量值會變成startoffset。對于setEnd()
來說,參照節(jié)點會變成endContainer,而偏移量值會變成endOffset??梢允褂眠@兩個方法來模仿selectNode()
和selectNodeContents()
。
來看下面的例子
var range1 = document.createRange(); var range2 = document.createRange(); var p1 = document.getElementById("p1"); var p1Index = -1; var i, len; for (i=0, len=p1.parentNode.childNodes.length; i < len; i++) { if (p1.parentNode.childNodes[i] == p1) { p1Index = i; break; } } range1.setStart(p1.parentNode, p1Index); range1.setEnd(p1.parentNode, p1Index + 1); range2.setStart(p1, 0); range2.setEnd(p1, p1.childNodes.length);
顯然,要選擇這個節(jié)點(使用range1),就必須確定當前節(jié)點(p1)在其父節(jié)點的childNodes集合中的索引。而要選擇這個節(jié)點的內(nèi)容(使用range2),也不必計算什么;只要通過setStart()和setEnd()設置默認值即可。模仿selectNode()
和selectNodeContents()
并不是setStart()
和setEnd()
的主要用途,它們更勝一籌的地方在于能夠選擇節(jié)點的一部分
假設只想選擇前面HTML示例代碼中從“Hello"的"llo"到"world!"的"o"——很容易做到
第一步是取得所有節(jié)點的引用,如下所示:
var p1 = document.getElementById("p1"); var helloNode = p1.firstChild.firstChild; var worldNode = p1.lastChild;
實際上,"Hello”文本節(jié)點是<p>元素的孫子節(jié)點,因為它本身是<b>元素的一個子節(jié)點。因此,p1.firstchild
取得的是<b>,而p1.firstchild.firstchild
取得的才是這個文本節(jié)點。"world!"文本節(jié)點是<p>元素的第二個子節(jié)點(也是最后一個子節(jié)點),因此可以使用p1.lastChild
取得該節(jié)點。
然后,必須在創(chuàng)建范圍時指定相應的起點和終點,如下所示
var range = document.createRange(); range.setStart(helloNode, 2); range.setEnd(worldNode, 3);
因為這個范圍的選區(qū)應該從"Hello"中"e"的后面開始,所以在setStart()
中傳入helloNode的同時,傳入了偏移量2(即"e"的下一個位置;"H"的位置是0)。設置選區(qū)的終點時,在setEnd()
中傳入worldNode的同時傳入了偏移量3,表示選區(qū)之外的第一個字符的位置,這個字符是”r",它的位置是3(位置0上還有一個空格)。
如下所示
由于helloNode和worldNode都是文本節(jié)點,因此它們分別變成了新建范圍的startContainer和endContainer。此時startoffset和endOffset分別用以確定兩個節(jié)點所包含的文本中的位置,而不是用以確定子節(jié)點的位置(就像傳入的參數(shù)為元素節(jié)點時那樣)。此時的commonAncestorContainer是<p>元素,也就是同時包含這兩個節(jié)點的第一個祖先元素
當然,僅僅是選擇了文檔中的某一部分用處并不大。但重要的是,選擇之后才可以對選區(qū)進行操作
操作范圍內(nèi)容
在創(chuàng)建范圍時,內(nèi)部會為這個范圍創(chuàng)建一個文檔片段,范圍所屬的全部節(jié)點都被添加到了這個文檔片段中。為了創(chuàng)建這個文檔片段,范圍內(nèi)容的格式必須正確有效。在前面的例子中,創(chuàng)建的選區(qū)分別開始和結束于兩個文本節(jié)點的內(nèi)部,因此不能算是格式良好的DOM結構,也就無法通過DOM來表示。但是,范圍知道自身缺少哪些開標簽和閉標簽,它能夠重新構建有效的DOM結構以便對其進行操作
對于前面的例子而言,范圍經(jīng)過計算知道選區(qū)中缺少一個開始的<b>標簽,因此就會在后臺動態(tài)加入一個該標簽,同時還會在前面加入一個表示結束的</b>標簽以結束"He"。于是,修改后的DOM就變成了如下所示
<p><b>He</b><b>llo</b> world!</p>
另外,文本節(jié)點"world!"也被拆分為兩個文本節(jié)點,一個包含"wo",另一個包含"rid!"。最終的DOM樹下圖所示,右側是表示范圍的文檔片段的內(nèi)容
像這樣創(chuàng)建了范圍之后,就可以使用各種方法對范圍的內(nèi)容進行操作了
[注意]表示范圍的內(nèi)部文檔片段中的所有節(jié)點,都只是指向文檔中相應節(jié)點的指針
【deleteContents()】
操作范圍內(nèi)容的第一個方法是deleteContents()
,這個方法能夠從文檔中刪除范圍所包含的內(nèi)容
var p1 = document.getElementById("p1"); var helloNode = p1.firstChild.firstChild; var worldNode = p1.lastChild; var range = document.createRange(); range.setStart(helloNode, 2); range.setEnd(worldNode, 3); range.deleteContents();
執(zhí)行以上代碼后,頁面中會顯示如下HTML代碼
<p><b>He</b>rld!</p>
由于范圍選區(qū)在修改底層DOM結構時能夠保證格式良好,因此即使內(nèi)容被刪除了,最終的DOM結構依舊是格式良好的
【extractContents()】
與deleteContents()
方法相似,extractContents()
方法也會從文檔中移除范圍選區(qū)。但區(qū)別在于,extractContents()
會返回范圍的文檔片段。利用這個返回的值,可以將范圍的內(nèi)容插入到文檔中的其他地方。如下所示:
var p1 = document.getElementById("p1"); var helloNode = p1.firstChild.firstChild; var worldNode = p1.lastChild; var range = document.createRange(); range.setStart(helloNode, 2); range.setEnd(worldNode, 3); var fragment = range.extractContents(); p1.parentNode.appendChild(fragment);
在這個例子中,將提取出來的文檔片段添加到了文檔<body>元素的末尾
[注意]在將文檔片段傳入appendChild()方法中時,添加到文檔中的只是片段的子節(jié)點,而非片段本身
<p><b>He</b>rld!</p> <b>llo</b> wo
【cloneContents】
還有一種做法是使用cloneContents()
創(chuàng)建范圍對象的一個副本,然后在文檔其他地方插入該副本
var p1 = document.getElementById("p1"); var helloNode = p1.firstChild.firstChild; var worldNode = p1.lastChild; var range = document.createRange(); range.setStart(helloNode, 2); range.setEnd(worldNode, 3); var fragment = range.cloneContents(); p1.parentNode.appendChild(fragment);
這個方法與extractContents()
非常類似,因為它們都返回文檔片段。它們的主要區(qū)別在于,cloneContents()
返回的文檔片段包含的是范圍中節(jié)點的副本,而不是實際的節(jié)點。執(zhí)行上面的操作后,頁面中的HTML代碼如下所示:
<p><b>Hello</b> world!</p> <b>llo</b> wo
[注意]在調(diào)用cloneContents()方法之前,拆分的節(jié)點并不會產(chǎn)生格式良好的文檔片段。換句話說,原始的HTML在DOM被修改之前會始終保持不變
插入范圍內(nèi)容
利用范圍,可以刪除或復制內(nèi)容,還可以像前面介紹的那樣操作范圍中的內(nèi)容。使用insertNode()
方法可以向范圍選區(qū)的開始處插入一個節(jié)點。假設在前面例子中的HTML前面插入以下HTML代碼
<span >Inserted text</span>
那么可以使用下列代碼:
var p1 = document.getElementById("p1"); var helloNode = p1.firstChild.firstChild; var worldNode = p1.lastChild; var range = document.createRange(); var span = document.createElement("span"); range.setStart(helloNode, 2); range.setEnd(worldNode, 3); span.style.color = "red"; span.appendChild(document.createTextNode("Inserted text")); range.insertNode(span);
運行以上javascript代碼,就會得到如下HTML代碼
<p id="p1"><b>He<span styie="color:red">Inserted text</span>llo</b> world</p>
[注意]<span>正好被插入到了"Hello"中的"llo"前面,而該位置就是范圍選區(qū)的開始位置。使用這種技術可以插入一些幫助提示信息,例如在打開新窗口的鏈接旁邊插入一幅圖像
【surroundContents()】
除了向范圍內(nèi)部插入內(nèi)容之外,還可以環(huán)繞范圍插入內(nèi)容,此時就要使用surroundContents()
方法。這個方法接受一個參數(shù),即環(huán)繞范圍內(nèi)容的節(jié)點。在環(huán)繞范圍插入內(nèi)容時,后臺會執(zhí)行下列步驟
1、提取出范圍中的內(nèi)容(類似執(zhí)行extractContents()
)
2、將給定節(jié)點插入到文檔中原來范圍所在的位置上
3、將文檔片段的內(nèi)容添加到給定節(jié)點中
可以使用這種技術來突出顯示網(wǎng)頁中的某些詞句,例如下列代碼
var p1 = document.getElementById("p1"); var helloNode = p1.firstChild.firstChild; var worldNode = p1.lastChild; var range = document.createRange(); range.selectNode(helloNode); var span = document.createElement("span"); span.style.backgroundColor = "yellow"; range.surroundContents(span);
以上代碼會給范圍選區(qū)加上一個黃色的背景。得到的HTML代碼如下所示
<p><b><span >Hello</b> world!</p>
為了插入<span>,范圍必須包含整個DOM選區(qū),而不能僅僅包含選中的DOM節(jié)點
折疊范圍
所謂折疊范圍,就是指范圍中未選擇文檔的任何部分??梢杂梦谋究騺砻枋稣郫B范圍的過程。假設文本框中有一行文本,用鼠標選擇了其中一個完整的單詞。然后,單擊鼠標左鍵,選區(qū)消失,而光標則落在了其中兩個字母之間。同樣,在折疊范圍時,其位置會落在文檔中的兩個部分之間,可能是范圍選區(qū)的開始位置,也可能是結束位置。下圖展示了折疊范圍時發(fā)生的情形
【collapse()】
使用collapse()
方法來折疊范圍,這個方法接受一個參數(shù),該參數(shù)是一個布爾值,表示要折疊到范圍的哪一端。參數(shù)true表示折疊到范圍的起點,參數(shù)false表示折疊到范圍的終點。要確定范圍已經(jīng)折疊完畢,可以檢査collapsed屬性,如下所示:
range.collapse(true);//折疊到起點 console.log(range.collapsed);//輸出true
檢測某個范圍是否處于折疊狀態(tài),可以幫我們確定范圍中的兩個節(jié)點是否緊密相鄰。例如,對于下面的HTML代碼
<p id="p1">Paragraph 1</p><p id="p2">Paragraph 2</p>
如果不知道其實際構成(比如說,這行代碼是動態(tài)生成的),那么可以像下面這樣創(chuàng)建一個范圍
var p1 = document.getElementById("p1"); var p2 = document.getElementById("p2"); var range = document.createRange(); range.setStartAfter(p1); range.setStartBefore(p2); console.log(range.collapsed);//輸出true
在這個例子中,新創(chuàng)建的范圍是折疊的,因為p1的后面和p2的前面什么也沒有
比較范圍
【compareBoundaryPoints()】
在有多個范圍的情況下,可以使用compareBoundaryPoints()
方法來確定這些范圍是否有公共的邊界(起點或終點)。這個方法接受兩個參數(shù):表示比較方式的常量值和要比較的范圍。表示比較方式的常量值如下所示
Range.START_TO_START(0)
:比較第一個范圍和第二個范圍的起點
Range.START_TO_END(1)
:比較第一個范圍的起點和第二個范圍的終點
Range.END_TO_END⑵
:比較第一個范圍和第二個范圍的終點
Range.END_T0_START(3)
:比較第一個范圍的終點和第一個范圍的起點
compareBoundaryPoints()
方法可能的返回值如下:如果第一個范圍中的點位于第二個范圍中的點之前,返回-1;如果兩個點相等,返回0;如果第一個范圍中的點位于第二個范圍中的點之后,返回1。
來看下面的例子
var range1 = document.createRange(); var range2 = document.createRange(); var p1 = document.getElementById("p1"); range1.selectNodeContents(p1); range2.selectNodeContents(p1); range2.setEndBefore(p1.lastChild); alert(range1.compareBoundaryPoints(Range.START_TO_START, range2)); //outputs 0 alert(range1.compareBoundaryPoints(Range.END_TO_END, range2)); //outputs 1
在這個例子中,兩個范圍的起點實際上是相同的,因為它們的起點都是由selectNodeContents()
方法設置的默認值來指定的。因此,第一次比較返回0。但是,range2的終點由于調(diào)用setEndBefore()
已經(jīng)改變了,結果是range1的終點位于range2的終點后面,因此第二次比較返回1
復制范圍
【cloneRange】
可以使用cloneRange()
方法復制范圍。這個方法會創(chuàng)建調(diào)用它的范圍的一個副本
var newRange = range.cloneRange();
新創(chuàng)建的范圍與原來的范圍包含相同的屬性,而修改它的端點不會影響原來的范圍
清理范圍
【detach()】
在使用完范圍之后,最好是調(diào)用detach()
方法,以便從創(chuàng)建范圍的文檔中分離出該范圍。調(diào)用detach()
之后,就可以放心地解除對范圍的引用,從而讓垃圾回收機制回收其內(nèi)存了。來看下面的例子
range.detach();//從文檔中分離 range = null;//解除引用
在使用范圍的最后再執(zhí)行這兩個步驟是推薦的方式。一且分離范圍,就不能再恢復使用了
IE兼容
IE8-瀏覽器不支持DOM范圍。但支持一種類似的概念,即文本范圍(textrange)。文本范圍是IE專有的特性,其他瀏覽器都不支持。顧名思義,文本范圍處理的主要是文本(不一定是DOM節(jié)點)。通過<body>、<button>、<input>和<textarea>等這幾個元素,可以調(diào)用createTextRange()
方法來創(chuàng)建文本范圍。以下是一個例子
var range = document.body.createTextRange();
像這樣通過document創(chuàng)建的范圍可以在頁面中的任何地方使用(通過其他元素創(chuàng)建的范圍則只能在相應的元素中使用)。與DOM范圍類似,使用IE文本范圍的方式也有很多種
一、簡單選擇
【findText()】
選擇頁面中某一區(qū)域的最簡單方式,就是使用范圍的findText()
方法。這個方法會找到第一次出現(xiàn)的給定文本,并將范圍移過來以環(huán)繞該文本。如果沒有找到文本,這個方法返回false;否則返回true。同樣,仍然以下面的HTML代碼為例
<p id="p1"><b>Hello</b> world!</p>
要選擇"Hello",可以使用下列代碼
var range = document.body.createTextRange(); var found = range.findText("Hello");
執(zhí)行完第二行代碼后,文本"Hello"就被包圍在范圍之內(nèi)了。為此,可以檢査范圍的text屬性來確認(這個屬性返回范圍中包含的文本),或者也可以檢查findText()
的返回值——在找到了文本的情況下返回值為true。
例如:
alert(found); //true alert(range.text); //"Hello"
還可以為findText()
傳入另一個參數(shù),即一個表示向哪個方向繼續(xù)搜索的數(shù)值。負值表示應該從當前位置向后搜索,而正值表示應該從當前位置向前搜索。因此,要査找文檔中前兩個"Hello"的實例,應該使用下列代碼
var found = range.findText("Hello"); var foundAgain = range.findText("Hello", 1);
【moveToElementText()】
IE中與DOM中的selectNode()方法最接近的方法是moveToElementText()
,這個方法接受一個DOM元素,并選擇該元素的所有文本,包括HTML標簽。下面是一個例子
var range = document.body.createTextRange(); var p1 = document.getElementById("p1") range.moveToElementText(p1);
在文本范圍中包含HTML的情況下,可以使用htmlText屬性取得范圍的全部內(nèi)容,包括HTML和文本,如下所示
alert(range.htmlText);
IE的范圍沒有任何屬性可以隨著范圍選區(qū)的變化而動態(tài)更新。不過,parentElement()
方法倒是與DOM的 commonAncestorContainer屬性類似
var ancestor = range.parentElement();
這樣得到的父元素始終都可以反映文本選區(qū)的父節(jié)點
二、復雜選擇
在IE中創(chuàng)建復雜范圍的方法,就是以特定的增量向四周移動范圍。為此,IE提供了4個方法:move()
、moveStart()
、moveEnd()
和expand()
。這些方法都接受兩個參數(shù):移動單位和移動單位的數(shù)量。
其中,移動單位是下列一種字符串值
"character":逐個字符地移動
"word":逐個單詞(一系列非空格字符)地移動
"sentence":逐個句子(一系列以句號、問號或嘆號結尾的字符)地移動
"textedit":移動到當前范圍選區(qū)的開始或結束位置
通過moveStart()
方法可以移動范圍的起點,通過moveEnd()
方法可以移動范圍的終點,移動的幅度由單位數(shù)量指定,如下所示
range.moveStart("word", 2);//起點移動2個單詞 range.moveEnd("character", 1);//終點移動1個字符
使用expand()
方法可以將范圍規(guī)范化。換句話說,expand()
方法的作用是將任何部分選擇的文本全部選中。例如,當前選擇的是一個單詞中間的兩個字符,調(diào)用expand("word")
可以將整個單詞都包含在范圍之內(nèi)
而move()方法則首先會折疊當前范圍(讓起點和終點相等),然后再將范圍移動指定的單位數(shù)量,如下所示
range.move("character", 5);//移動5個字符
調(diào)用move()
之后,范圍的起點和終點相同,因此必須再使用moveStart()
或moveEnd()
創(chuàng)建新的選區(qū)
三、操作范圍內(nèi)容
在IE中操作范圍中的內(nèi)容可以使用text屬性或pasteHTML()
方法。如前所述,通過text屬性可以取得范圍中的內(nèi)容文本;但是,也可以通過這個屬性設置范圍中的內(nèi)容文本。來看一個例子
var range = document.body.createTextRange(); range.findText("Hello"); range.text = "Howdy";
如果仍以前面的Hello World代碼為例,執(zhí)行以上代碼后的HTML代碼如下
<p id="p1"><b>Howdy</b> world!</p>
[注意]在設置text屬性的情況下,HTML標簽保持不變
【pasteHTML()】
要向范圍中插入HTML代碼,就得使用pasteHTML()
方法,如下所示
var range = document.body.createTextRange(); range.findText("Hello"); range.pasteHTML("<em>Howdy</em>");
執(zhí)行這些代碼后,會得到如下HTML
<p id="p1"><b><em>Howdy</em></b> world!</p>
不過,在范圍中包含HTML代碼時,不應該使用pasteHTML()
,因為這樣很容易導致不可預料的結果——很可能是格式不正確的HTML
四、折疊IE范圍
【collapse()】
IE為范圍提供的collapse()
方法與相應的DOM方法用法一樣:傳入true把范圍折疊到起點,傳入false把范圍折疊到終點。例如:
range.collapse(true); //折疊到起點
可惜的是,沒有對應的collapsed屬性讓我們知道范圍是否已經(jīng)折疊完畢。為此,必須使用boundingWidth屬性,該屬性返回范圍的寬度(以像素為單位)。如果boundingwidth屬性等于0,就說明范圍已經(jīng)折疊了
var isCollapsed = (range.boundingWidth == 0);
此外,還有boundingHeight、boundingLeft和boundingTop等屬性,雖然它們都不像boundingWidth那么有用,但也可以提供一些有關范圍位置的信息
五、比較IE范圍
【compareEndPoints()】
IE中的compareEndPoints()
方法與DOM范圍的compareBoundaryPoints()
方法類似。這個方法接受兩個參數(shù):比較的類型和要比較的范圍。比較類型的取值范圍是下列幾個字符串值:"StartToStart"、"StartToEnd"、"EndToEnd"和"EndToStart"。這幾種比較類型與比較DOM范圍時使用的幾個值是相同的
同樣與DOM類似的是,compareEndPoints()
方法也會按照相同的規(guī)則返回值,即如果第一個范圍的邊界位于第二個范圍的邊界前面,返回-1;如果二者邊界相同,返回0;如果第一個范圍的邊界位于第二個范圍的邊界后面,返回1。仍以前面的Hello World代碼為例,下列代碼將創(chuàng)建兩個范圍,一個選擇"Hello world!"(包括<b>標簽),另一個選擇"Hello"
var range1 = document.body.createTextRange(); var range2 = document.body.createTextRange(); range1.findText("Hello world!"); range2.findText("Hello"); alert(range1.compareEndPoints("StartToStart", range2)); //outputs 0 alert(range1.compareEndPoints("EndToEnd", range2)); //outputs 1;
由于這兩個范圍共享同一個起點,所以使用compareEndPoints()
比較起點返回0。而range1的終點在range2的終點后面,所以compareEndPoints()
返回1
IE中還有兩個方法,也是用于比較范圍的:isEqual()用于確定兩個范圍是否相等,inRange()
用于確定一個范圍是否包含另一個范圍。
下面是相應的示例
var range1 = document.body.createTextRange(); var range2 = document.body.createTextRange(); range1.findText("Hello world!"); range2.findText("Hello"); alert("range1.isEqual(range2): " + range1.isEqual(range2));//false alert("range1.inRange(range2): " + range1.inRange(range2));//true
這個例子使用了與前面相同的范圍來示范這兩個方法。由于這兩個范圍的終點不同,所以它們不相等,調(diào)用isEqual返回false。由于range2實際位于rangel內(nèi)部,它的終點位于后者的終點之前、起點之后,所以range2被包含在rangel內(nèi)部,調(diào)用inRange()
返回true
六、復制IE范圍
在IE中使用duplicate()
方法可以復制文本范圍,結果會創(chuàng)建原范圍的一個副本,如下所示
var newRange = range.duplicate();
新創(chuàng)建的范圍會帶有與原范圍完全相同的屬性
以上是“Javascript中DOM范圍的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關知識,歡迎關注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。