DOM範圍

来源:http://www.cnblogs.com/xiaohuochai/archive/2017/02/11/6387710.html
-Advertisement-
Play Games

[1]創建範圍 [2]簡單選擇 [3]複雜選擇 [4]操作範圍內容 [5]插入範圍內容 [6]摺疊範圍 [7]比較範圍 [8]複製範圍 [9]清理範圍 [10]IE相容 ...


前面的話

  為了讓開發人員更方便地控制頁面,DOM定義了“範圍”(range)介面。通過範圍可以選擇文檔中的一個區域,而不必考慮節點的界限(選擇在後臺完成,對用戶是不可見的)。在常規的DOM操作不能更有效地修改文擋時,使用範圍往往可以達到目的。本文將詳細介紹DOM範圍

 

創建範圍

  Document類型中定義了createRange()方法。在相容DOM的瀏覽器中,這個方法屬於document對象。使用hasFeature()或者直接檢測該方法,都可以確定瀏覽器是否支持範圍

  [註意]IE8-瀏覽器不支持

var supportsRange = document.implementation.hasFeature("Range", "2.0");
var alsoSupportsRange =(typeof document.createRange == "function");

  如果瀏覽器支持範圍,那麼就可以使用createRange()來創建DOM範圍,如下所示

var range = document.createRange();

  與節點類似,新創建的範圍也直接與創建它的文檔關聯在一起,不能用於其他文檔。創建了範圍之後,接下來就可以使用它在後臺選擇文檔中的特定部分。而創建範圍並設置了其位置之後,還可以針對範圍的內容執行很多種操作,從而實現對底層DOM樹的更精細的控制

  每個範圍由一個Range類型的實例表示,這個實例擁有很多屬性和方法。下列屬性提供了當前範圍在文檔中的位置信息

startContainer:包含範圍起點的節點(即選區中第一個節點的父節點)
startoffset:範圍在startContainer中起點的偏移量。如果startContainer是文本節點、註釋節點或CDATA節點,那麼startoffset就是範圍起點之前跳過的字元數量。否則,startoffset就是範圍中第一個子節點的索引
endContainer:包含範圍終點的節點(即選區中最後一個節點的父節點)
endOffset:範圍在endContainer中終點的偏移量(與startoffset遵循相同的取值規則)
commonAncestorContainer:startContainer和endContainer共同的祖先節點在文檔樹中位置最深的那個

  在把範圍放到文檔中特定的位置時,這些屬性都會被賦值

 

簡單選擇

  要使用範圍來選擇文檔中的一部分,最簡單的方式就是使用selectNode()或selectNodeContents()。這兩個方法都接受一個參數,即一個DOM節點,然後使用該節點中的信息來填充範圍。其中,selectNode()方法選擇整個節點,包括其子節點;而selectNodeContents()方法則只選擇節點的子節點

<!DOCTYPE html>
<html>
    <body>
        <p id="p1"><b>Hello</b> world!</p>
    </body>
</html>

  我們可以使用下列代碼來創建範圍

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);

  這裡創建的兩個範圍包含文檔中不同的部分:rangl包含<p>元素及其所有子元素,而rang2包含<b>元素、文本節點"Hello"和文本節點"world!"

  在調用selectNode()時,startContainer、endContainer和commonAncestorContainer都等於傳入節點的父節點,也就是這個例子中的document.body。而startoffset屬性等於給定節點在其父節點的childNodes集合中的索引(在這個例子中是1——因為相容DOM的瀏覽器將空格算作一個文本節點),endOffset等於startoffset加1(因為只選擇了一個節點)

  在調用selectNodeContents()時,startContainer、endContainer和commonAncestorContainer等於傳入的節點,即這個例子中的<p>元素。而startoffset屬性始終等於0,因為範圍從給定節點的第一個子節點開始。最後,endOffset等於子節點的數量(node.childNodes.length),在這個例子中是2

  此外,為了更精細地控制將哪些節點包含在範圍中,還可以使用下列方法

setStartBefore(refNode):將範圍的起點設置在refNode之前,因此refNode也就是範圍選區中的第一個子節點。同時會將startContainer屬性設置為refNode.parentNode,將startoffset屬性設置為refNode在其父節點的childNodes集合中的索引
setStartAfter(refNode):將範圍的起點設置在refNode之後,因此refNode也就不在範圍之內了,其下一個同輩節點才是範圍選區中的第一個子節點。同時會將startContainer屬性設置為refNode.parentNode,將startoffset屬性設置為refNode在其父節點的childNodes集合中的索引加1
setEndBefore(refNode):將範圍的終點設置在refNode之前,因此refNode也就不在範圍之內了,其上一個同輩節點才是範圍選區中的最後一個子節點。同時會將endContainer屬性設置為refNode.parentNode,將endOffset屬性設置為refNode在其父節點的childNodes集合中的索引
setEndAfter(refNode):將範圍的終點設置在refNode之後,因此refNode也就是範圍選區中的最後一個子節點。同時會將endContainer屬性設置為refNode.parentNode,將endOffset屬性設置為refNode在其父節點的childNodes集合中的索引加1

  調用這些方法時,所有屬性會自動設置好。不過,要想創建複雜的範圍選區,也可以直接指定這些屬性的值

 

複雜選擇

  要創建複雜的範圍就得使用setStart()和setEnd()方法。這兩個方法都接受兩個參數:一個參照節點和一個偏移量值。對setStart()來說,參照節點會變成startContainer。而偏移量值會變成startoffset。對於setEnd()來說,參照節點會變成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);

  顯然,要選擇這個節點(使用range1),就必須確定當前節點(p1)在其父節點的childNodes集合中的索引。而要選擇這個節點的內容(使用range2),也不必計算什麼;只要通過setStart()和setEnd()設置預設值即可。模仿selectNode()和selectNodeContents()並不是setStart()和setEnd()的主要用途,它們更勝一籌的地方在於能夠選擇節點的一部分

  假設只想選擇前面HTML示例代碼中從“Hello"的"llo"到"world!"的"o"——很容易做到

  第一步是取得所有節點的引用,如下所示:

var p1 = document.getElementById("p1");
var helloNode = p1.firstChild.firstChild;
var worldNode = p1.lastChild;

  實際上,"Hello”文本節點是<p>元素的孫子節點,因為它本身是<b>元素的一個子節點。因此,p1.firstchild取得的是<b>,而p1.firstchild.firstchild取得的才是這個文本節點。"world!"文本節點是<p>元素的第二個子節點(也是最後一個子節點),因此可以使用p1.lastChild取得該節點。然後,必須在創建範圍時指定相應的起點和終點,如下所示

var range = document.createRange();
range.setStart(helloNode, 2);
range.setEnd(worldNode, 3);

  因為這個範圍的選區應該從"Hello"中"e"的後面開始,所以在setStart()中傳入helloNode的同時,傳入了偏移量2(即"e"的下一個位置;"H"的位置是0)。設置選區的終點時,在setEnd()中傳入worldNode的同時傳入了偏移量3,表示選區之外的第一個字元的位置,這個字元是”r",它的位置是3(位置0上還有一個空格)。如下所示

  由於helloNode和worldNode都是文本節點,因此它們分別變成了新建範圍的startContainer和endContainer。此時startoffset和endOffset分別用以確定兩個節點所包含的文本中的位置,而不是用以確定子節點的位置(就像傳入的參數為元素節點時那樣)。此時的commonAncestorContainer是<p>元素,也就是同時包含這兩個節點的第一個祖先元素

  當然,僅僅是選擇了文檔中的某一部分用處並不大。但重要的是,選擇之後才可以對選區進行操作

 

操作範圍內容

  在創建範圍時,內部會為這個範圍創建一個文檔片段,範圍所屬的全部節點都被添加到了這個文檔片段中。為了創建這個文檔片段,範圍內容的格式必須正確有效。在前面的例子中,創建的選區分別開始和結束於兩個文本節點的內部,因此不能算是格式良好的DOM結構,也就無法通過DOM來表示。但是,範圍知道自身缺少哪些開標簽和閉標簽,它能夠重新構建有效的DOM結構以便對其進行操作

  對於前面的例子而言,範圍經過計算知道選區中缺少一個開始的<b>標簽,因此就會在後臺動態加入一個該標簽,同時還會在前面加入一個表示結束的</b>標簽以結束"He"。於是,修改後的DOM就變成瞭如下所示

<p><b>He</b><b>llo</b> world!</p>

  另外,文本節點"world!"也被拆分為兩個文本節點,一個包含"wo",另一個包含"rid!"。最終的DOM樹下圖所示,右側是表示範圍的文檔片段的內容

  像這樣創建了範圍之後,就可以使用各種方法對範圍的內容進行操作了

  [註意]表示範圍的內部文檔片段中的所有節點,都只是指向文檔中相應節點的指針

【deleteContents()】

  操作範圍內容的第一個方法是deleteContents(),這個方法能夠從文檔中刪除範圍所包含的內容

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();

  執行以上代碼後,頁面中會顯示如下HTML代碼

<p><b>He</b>rld!</p>

  由於範圍選區在修改底層DOM結構時能夠保證格式良好,因此即使內容被刪除了,最終的DOM結構依舊是格式良好的

【extractContents()】

  與deleteContents()方法相似,extractContents()方法也會從文檔中移除範圍選區。但區別在於,extractContents()會返回範圍的文檔片段。利用這個返回的值,可以將範圍的內容插入到文檔中的其他地方。如下所示:

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()方法中時,添加到文檔中的只是片段的子節點,而非片段本身

<p><b>He</b>rld!</p>
<b>llo</b> wo

【cloneContents】

  還有一種做法是使用cloneContents()創建範圍對象的一個副本,然後在文檔其他地方插入該副本

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()非常類似,因為它們都返迴文檔片段。它們的主要區別在於,cloneContents()返回的文檔片段包含的是範圍中節點的副本,而不是實際的節點。執行上面的操作後,頁面中的HTML代碼如下所示:

<p><b>Hello</b> world!</p>
<b>llo</b> wo

  [註意]在調用cloneContents()方法之前,拆分的節點並不會產生格式良好的文檔片段。換句話說,原始的HTML在DOM被修改之前會始終保持不變

 

插入範圍內容

  利用範圍,可以刪除或複製內容,還可以像前面介紹的那樣操作範圍中的內容。使用insertNode()方法可以向範圍選區的開始處插入一個節點。假設在前面例子中的HTML前面插入以下HTML代碼

<span style="color: red">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"前面,而該位置就是範圍選區的開始位置。使用這種技術可以插入一些幫助提示信息,例如在打開新視窗的鏈接旁邊插入一幅圖像

【surroundContents()】

  除了向範圍內部插入內容之外,還可以環繞範圍插入內容,此時就要使用surroundContents()方法。這個方法接受一個參數,即環繞範圍內容的節點。在環繞範圍插入內容時,後臺會執行下列步驟

  1、提取出範圍中的內容(類似執行extractContents())

  2、將給定節點插入到文檔中原來範圍所在的位置上

  3、將文檔片段的內容添加到給定節點中

  可以使用這種技術來突出顯示網頁中的某些詞句,例如下列代碼

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);

  以上代碼會給範圍選區加上一個黃色的背景。得到的HTML代碼如下所示

<p><b><span style="background-color:yellow">Hello</b> world!</p>

  為了插入<span>,範圍必須包含整個DOM選區,而不能僅僅包含選中的DOM節點

 

摺疊範圍

  所謂摺疊範圍,就是指範圍中未選擇文檔的任何部分。可以用文本框來描述摺疊範圍的過程。假設文本框中有一行文本,用滑鼠選擇了其中一個完整的單詞。然後,單擊滑鼠左鍵,選區消失,而游標則落在了其中兩個字母之間。同樣,在摺疊範圍時,其位置會落在文檔中的兩個部分之間,可能是範圍選區的開始位置,也可能是結束位置。下圖展示了摺疊範圍時發生的情形 

【collapse()】

  使用collapse()方法來摺疊範圍,這個方法接受一個參數,該參數是一個布爾值,表示要摺疊到範圍的哪一端。參數true表示摺疊到範圍的起點,參數false表示摺疊到範圍的終點。要確定範圍已經摺疊完畢,可以檢査collapsed屬性,如下所示:

range.collapse(true);//摺疊到起點
console.log(range.collapsed);//輸出true

  檢測某個範圍是否處於摺疊狀態,可以幫我們確定範圍中的兩個節點是否緊密相鄰。例如,對於下麵的HTML代碼

<p id="p1">Paragraph 1</p><p id="p2">Paragraph 2</p>

  如果不知道其實際構成(比如說,這行代碼是動態生成的),那麼可以像下麵這樣創建一個範圍

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

  在這個例子中,新創建的範圍是摺疊的,因為p1的後面和p2的前面什麼也沒有

 

比較範圍

【compareBoundaryPoints()】

  在有多個範圍的情況下,可以使用compareBoundaryPoints()方法來確定這些範圍是否有公共的邊界(起點或終點)。這個方法接受兩個參數:表示比較方式的常量值和要比較的範圍。表示比較方式的常量值如下所示

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的終點由於調用setEndBefore()已經改變了,結果是range1的終點位於range2的終點後面,因此第二次比較返回1

 

複製範圍

【cloneRange】

  可以使用cloneRange()方法複製範圍。這個方法會創建調用它的範圍的一個副本

var newRange = range.cloneRange();

  新創建的範圍與原來的範圍包含相同的屬性,而修改它的端點不會影響原來的範圍

 

清理範圍

【detach()】

  在使用完範圍之後,最好是調用detach()方法,以便從創建範圍的文檔中分離出該範圍。調用detach()之後,就可以放心地解除對範圍的引用,從而讓垃圾回收機制回收其記憶體了。來看下麵的例子

range.detach();//從文檔中分離
range = null;//解除引用

  在使用範圍的最後再執行這兩個步驟是推薦的方式。一且分離範圍,就不能再恢復使用了

 

IE相容

  IE8-瀏覽器不支持DOM範圍。但支持一種類似的概念,即文本範圍(textrange)。文本範圍是IE專有的特性,其他瀏覽器都不支持。顧名思義,文本範圍處理的主要是文本(不一定是DOM節點)。通過<body>、<button>、<input>和<textarea>等這幾個元素,可以調用createTextRange()方法來創建文本範圍。以下是一個例子

var range = document.body.createTextRange();

  像這樣通過document創建的範圍可以在頁面中的任何地方使用(通過其他元素創建的範圍則只能在相應的元素中使用)。與DOM範圍類似,使用IE文本範圍的方式也有很多種

一、簡單選擇

【findText()】

  選擇頁面中某一區域的最簡單方式,就是使用範圍的findText()方法。這個方法會找到第一次出現的給定文本,並將範圍移過來以環繞該文本。如果沒有找到文本,這個方法返回false;否則返回true。同樣,仍然以下麵的HTML代碼為例

<p id="p1"><b>Hello</b> world!</p>

  要選擇"Hello",可以使用下列代碼

var range = document.body.createTextRange();
var found = range.findText("Hello");

  執行完第二行代碼後,文本"Hello"就被包圍在範圍之內了。為此,可以檢査範圍的text屬性來確認(這個屬性返回範圍中包含的文本),或者也可以檢查findText()的返回值——在找到了文本的情況下返回值為true。例如:

alert(found); //true
alert(range.text);    //"Hello"

  還可以為findText()傳入另一個參數,即一個表示向哪個方向繼續搜索的數值。負值表示應該從當前位置向後搜索,而正值表示應該從當前位置向前搜索。因此,要査找文檔中前兩個"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屬性取得範圍的全部內容,包括HTML和文本,如下所示

alert(range.htmlText);

  IE的範圍沒有任何屬性可以隨著範圍選區的變化而動態更新。不過,parentElement()方法倒是與DOM的 commonAncestorContainer屬性類似

var ancestor = range.parentElement();

  這樣得到的父元素始終都可以反映文本選區的父節點

二、複雜選擇

  在IE中創建複雜範圍的方法,就是以特定的增量向四周移動範圍。為此,IE提供了4個方法:move()、moveStart()、moveEnd()和expand()。這些方法都接受兩個參數:移動單位和移動單位的數量。其中,移動單位是下列一種字元串值

"character":逐個字元地移動
"word":逐個單詞(一系列非空格字元)地移動
"sentence":逐個句子(一系列以句號、問號或嘆號結尾的字元)地移動
"textedit":移動到當前範圍選區的開始或結束位置

  通過moveStart()方法可以移動範圍的起點,通過moveEnd()方法可以移動範圍的終點,移動的幅度由單位數量指定,如下所示

range.moveStart("word", 2);//起點移動2個單詞
range.moveEnd("character", 1);//終點移動1個字元

  使用expand()方法可以將範圍規範化。換句話說,expand()方法的作用是將任何部分選擇的文本全部選中。例如,當前選擇的是一個單詞中間的兩個字元,調用expand("word")可以將整個單詞都包含在範圍之內

  而move()方法則首先會摺疊當前範圍(讓起點和終點相等),然後再將範圍移動指定的單位數量,如下所示

range.move("character", 5);//移動5個字元

  調用move()之後,範圍的起點和終點相同,因此必須再使用moveStart()或moveEnd()創建新的選區

三、操作範圍內容

  在IE中操作範圍中的內容可以使用text屬性或pasteHTML()方法。如前所述,通過text屬性可以取得範圍中的內容文本;但是,也可以通過這個屬性設置範圍中的內容文本。來看一個例子

var range = document.body.createTextRange();
range.findText("Hello");
range.text = "Howdy";

  如果仍以前面的Hello World代碼為例,執行以上代碼後的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>");

  執行這些代碼後,會得到如下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屬性讓我們知道範圍是否已經摺疊完畢。為此,必須使用boundingWidth屬性,該屬性返回範圍的寬度(以像素為單位)。如果boundingwidth屬性等於0,就說明範圍已經摺疊了

var isCollapsed = (range.boundingWidth == 0);

  此外,還有boundingHeight、boundingLeft和boundingTop等屬性,雖然它們都不像boundingWidth那麼有用,但也可以提供一些有關範圍位置的信息

五、比較IE範圍

【compareEndPoints()】

  IE中的compareEndPoints()方法與DOM範圍的compareBoundaryPoints()方法類似。這個方法接受兩個參數:比較的類型和要比較的範圍。比較類型的取值範圍是下列幾個字元串值:"StartToStart"、"StartToEnd"、"EndToEnd"和"EndToStart"。這幾種比較類型與比較DOM範圍時使用的幾個值是相同的

  同樣與DOM類似的是,compareEndPoints()方法也會按照相同的規則返回值,即如果第一個範圍的邊界位於第二個範圍的邊界前面,返回-1;如果二者邊界相同,返回0;如果第一個範圍的邊界位於第二個範圍的邊界後面,返回1。仍以前面的Hello World代碼為例,下列代碼將創建兩個範圍,一個選擇"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

  這個例子使用了與前面相同的範圍來示範這兩個方法。由於這兩個範圍的終點不同,所以它們不相等,調用isEqual返回false。由於range2實際位於rangel內部,它的終點位於後者的終點之前、起點之後,所以range2被包含在rangel內部,調用inRange()返回true

六、複製IE範圍

  在IE中使用duplicate()方法可以複製文本範圍,結果會創建原範圍的一個副本,如下所示

var newRange = range.duplicate();

  新創建的範圍會帶有與原範圍完全相同的屬性


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 轉載網址:http://www.jb51.net/css/529846.html 前言 其實不管是三欄佈局還是兩欄佈局都是我們在平時項目里經常使用的,也許你不知道什麼事三欄佈局什麼是兩欄佈局但實際已經在用,或許你知道三欄佈局的一種或兩種方法,但實際操作中也只會依賴那某一種方法,本文具體的介紹了三欄布 ...
  • 如果你是一個人在自學前端開發,或者是對前端開發有比較濃厚的興趣正想踏入前端領域,只要你在前端自學路上遇到了自己無法解決的技術難題,那麼儘管將你的疑惑交給我的小伙伴兒們吧,我們都是一群在前端自學路上摸爬滾打的有志青年,希望你可以來和我們共同交流。同時也希望你能獻出自己的一份力,幫助我的小伙伴兒們解決他 ...
  • for...in主要用於對數組和對象的屬性進行遍歷。for ... in 迴圈中的代碼每執行一次,就會對數組的元素或者對象的屬性進行一次操作。 語法:for (variable in object) {...} 對數組操作 可以發現在for in函數中變數以字元串的形式出現,這時候在函數中操作a[x ...
  • JS腳本(jQuery)為圖片加水印效果預覽:http://hovertree.com/texiao/jquery/94/本功能使用HTML5實現,可為圖片加上文字水印,可設置文字,設置顏色,位置等,加水印的圖片需和網頁在同個功能變數名稱下。完整代碼如下: 源碼下載:http://hovertree.com ...
  • JavaScript 在瀏覽器中的性能成為開發者所面臨的最重要的可用性問題。而這個問題又因 JavaScript 的阻塞特性變的複雜,也就是說當瀏覽器在執行 JavaScript 代碼時,不能同時做其他任何事情。本文詳細介紹瞭如何正確的載入和執行 JavaScript 代碼,從而提高其在瀏覽器中的性... ...
  • 阻止預設事件 function stopDeFault(e){ if(e&&e.preventDefault){//非IE e.preventDefault(); }else{//IE window.event.returnValue=false; } } 阻止事件冒泡 function stopB ...
  • 一、前言: 當我們還在沉迷於ES5的時候,殊不知ES6早就已經發佈幾年了。時代在進步,WEB前端技術也在日新月異,是時候做些改變了! ECMAScript 6(ES6)的發展速度非常之快,但現代瀏覽器對ES6新特性支持度不高,所以要想在瀏覽器中直接使用ES6的新特性就得藉助別的工具來實現。 Babe ...
  • 單獨對接每個快遞公司的api會比較麻煩,一般都選擇第三方來對接 服務來源: 阿裡雲 付費(0.01元100次) 購買服務後,商家提供AppKey、AppSecret、AppCode 購買物流查詢介面api的服務,到官網上能找到各種程式語言對應的demo,稍微修改下就能正常使用.重溫下curl以及aj ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...