摘要:級遍歷和范圍模塊定義了范圍接口。折疊范圍方法折疊就是指范圍中未選擇文檔的任何部分。表示折疊到范圍的起點,參數(shù)表示折疊到范圍的終點。常量指定比較當前范圍的點和指定范圍的點。下節(jié)再討論及更早版本中的范圍
“DOM2級遍歷和范圍”模塊定義了“范圍”接口。通過范圍可以選擇文檔中的一個區(qū)域,而不必考慮節(jié)點的界限(選擇在后臺完成,對用戶是不可見的)。
DOM中的范圍DOM2級在Document類型中定義了createRange()方法,可以用來創(chuàng)建DOM范圍,如下所示:
var range = document.createRange();
每個范圍由一個Range類型的實例表示,這個實例有很多屬性和方法:
startContainer:包含范圍起點的節(jié)點(選區(qū)中第一個節(jié)點的父節(jié)點);
startOffset:范圍在startContainer中起點的偏移量;
endContainer:包含范圍終點的節(jié)點(選區(qū)中最后一個節(jié)點的父節(jié)點);
endOffset:范圍在endContainer中終點的偏移量;
commonAncestorContainer:startContainer和endContainer共同的祖先節(jié)點在文檔樹中位置最深的那個;
用DOM范圍實現(xiàn)簡單選擇 selectNode()或selectNodeContents()前者選擇整個節(jié)點,包括子節(jié)點;后者選擇節(jié)點的子節(jié)點。如:
Hello world!
在調(diào)用selectNode()時,startContainer、endContainer和commonAncestorContainer等都等于傳入節(jié)點的父節(jié)點,也就是其中的document.body。而startOffset屬性等于給定節(jié)點在其父節(jié)點的childNodes集合中的索引。endOffset等于startOffset加上1;
在調(diào)用selectNodeContents()時,startContainer、endContainer和commonAncestorContainer等于傳入的節(jié)點。而startOffset屬性始終等于0.最后,endOffset等于子節(jié)點的數(shù)量(node.childNodes.length);
更精細的選擇為了更精細的控制將哪些節(jié)點包含在范圍中,還可以使用下列方法:
setStartBefore(refNode):將范圍的起點設置在refNode之前;
setStartAfter(refNode):將范圍的起點設置在refNode之后;
setEndBefore(refNode):將范圍的終點設置在refNode之前;
setEndAfter(refNode):將范圍的終點設置在refNode之后;
如下html:
Hello world!
hello
js:
var range1 = document.createRange(), range2 = document.createRange(), p1 = document.getElementById("p1"); range1.selectNode(p1); range1.setStartAfter(p1); console.log(range1.startContainer); //document.body console.log(range1.startOffset); //2 有1個空格和一個p元素 console.log(range1.endContainer); //document.body console.log(range1.endOffset); //2 選擇了一個元素,所以是startOffset加1 console.log(range1.commonAncestorContainer); //document.body range2.setStartAfter(p1); //結(jié)果與上面的相同 console.log(range2.startContainer); //document.body console.log(range2.startOffset); //2 console.log(range2.endContainer); //document.body console.log(range2.endOffset); //2 console.log(range2.commonAncestorContainer); //document.body用DOM范圍實現(xiàn)更加復雜的選擇 setStart()和setEnd()方法
這兩個方法都接受兩個參數(shù):一個參照節(jié)點和一個偏移量值。對前者來說,參照節(jié)點會變成startContainer,偏移值則會變成startOffset。對于后者來說,參照節(jié)點會變成endContainer,偏移值會變成endOffset。
html:
Hello world!
js:
var p1 = document.getElementById("p1"), helloNode = p1.firstChild.firstChild, worldNode = p1.lastChild; var range = document.createRange(); range.setStart(helloNode, 2); range.setEnd(worldNode, 3);
這樣就完成了對“l(fā)lo wo”的選擇,但僅僅完成對該選區(qū)的選擇意義不大,重要的是對其進行操作。
操作DOM范圍中的內(nèi)容 deleteContents()刪除范圍所包含的內(nèi)容如:
Hello world!
舉例:
var p1 = document.getElementById("p1"); var hello = p1.firstChild.firstChild; var world = p1.lastChild; var range = document.createRange(); range.setStart(hello, 1); range.setEnd(world, 2); console.log(range.toString()); //ello w console.log(p1.outerHTML); //Hello world!
range.deleteContents(); //刪除範圍內(nèi)的內(nèi)容 console.log(p1.outerHTML); //Horld!
又如:
舉例:
var list = document.getElementById("list"); var starting = list.getElementsByTagName("li")[1]; var ending = list.getElementsByTagName("li")[3]; var range = document.createRange(); range.setStart(starting, 0); range.setEnd(ending, 0); console.log(range.toString()); console.log(list.outerHTML); range.deleteContents(); console.log(list.outerHTML);extractContents()移除范圍所包含的內(nèi)容并返回文檔片段
如:
Hello world!
舉例:
var p1 = document.querySelector("#p1"); var helloNode = p1.firstChild.firstChild, worldNode = p1.lastChild; var range = document.createRange(); range.setStart(helloNode, 2); range.setEnd(worldNode, 3); var fragment = range.extractContents(); p1.parentNode.insertBefore(fragment, p1);
又如:
舉例:
var list = document.getElementById("list"); var range = document.createRange(); var starting = list.getElementsByTagName("li")[1]; var ending = list.getElementsByTagName("li")[4]; range.selectNode(list); range.setStartBefore(starting); range.setEndBefore(ending); var fragment = range.extractContents(); document.body.appendChild(fragment); console.log(document.body.innerHTML); //
如:
var list = document.getElementById("list"); var range = document.createRange(); var starting = list.getElementsByTagName("li")[1]; var ending = list.getElementsByTagName("li")[4]; range.selectNode(list); range.setStartBefore(starting); range.setEndBefore(ending); var fragment = range.cloneContents(); document.body.appendChild(fragment); console.log(document.body.innerHTML); //
如:
代碼:
又如:
Hello world!
代碼:
var p = document.getElementById("p1");
var range = document.createRange();
var starting = p.firstChild.firstChild;
var ending = p.lastChild;
range.setStart(starting, 5);
range.setEnd(ending, 0);
var span = document.createElement("span");
span.appendChild(document.createTextNode(" there in this"));
range.insertNode(span);
console.log(p1.innerText); //Hello there in this world!
console.log(p1.innerHTML); //Hello there in this world!
surroundContents()向范圍選區(qū)周圍插入一個節(jié)點(圍繞范圍插入內(nèi)容)
通常與selectNode()配合,因為范圍必須包含整個DOM選區(qū),不能僅僅包含選中的DOM節(jié)點。
如:
Hello world!
代碼:
var p = document.getElementById("p1");
var range = document.createRange();
range.selectNode(p.firstChild);
var span = document.createElement("span");
span.style.border = "1px solid orange";
span.style.borderRadius = "3px";
range.surroundContents(span);
console.log(p1.innerHTML); //Hello world!
為了插入span標簽,范圍必須包含整個DOM選區(qū),所以推薦使用selectNode()配合。
折疊DOM范圍 collapse()方法折疊就是指范圍中未選擇文檔的任何部分。該函數(shù)接收一個參數(shù),一個布爾值。true表示折疊到范圍的起點,參數(shù)false表示折疊到范圍的終點。要確定范圍已經(jīng)折疊完畢,可以檢查collapsed屬性:
如:
Hello world!
代碼:
var p = document.getElementById("p1"); var range = document.createRange(); range.selectNode(p); range.collapse(true); console.log(range.collapsed); //True
又如:
代碼:
var list = document.querySelector("#list"); var range = document.createRange(); range.setStartAfter(list.getElementsByTagName("li")[1]); range.setEndBefore(list.getElementsByTagName("li")[2]); console.log(range.collapsed); //False 因為還有一個空白節(jié)點在這里 var range2 = document.createRange(); range2.setStartAfter(list.getElementsByTagName("li")[3]); range2.setEndBefore(list.getElementsByTagName("li")[4]); console.log(range2.collapsed); //True 因為范圍沒有選中任何部分比較DOM范圍 comopareBoundaryPoints()方法來比較
該方法涌來比較這些范圍是否有公共的邊界。接收兩個參數(shù):表示比較方式的常量值和要比較的范圍。如:
Range.START_TO_START - 比較兩個 Range 節(jié)點的開始點
Range.END_TO_END - 比較兩個 Range 節(jié)點的結(jié)束點
Range.START_TO_END - 用 sourceRange 的開始點與當前范圍的結(jié)束點比較
Range.END_TO_START - 用 sourceRange 的結(jié)束點與當前范圍的開始點比較
注意:《高級程序設計》一書中,對后兩個的說明太模糊(不正確?);下面是w3school的解釋:
您可能認為,首先需要用參數(shù) how 的范圍常量指定當前范圍的邊界點,然后再用它指定 sourceRange 的邊界點。但事實上,
常量 Range.START_TO_END 指定與當前范圍的 end 點和 sourceRange 的 start 點進行比較。
常量 Range.END_TO_START 指定比較當前范圍的 start 點和指定范圍的 end 點。
如果第一個范圍中的點位于第二個范圍中的點之前,返回-1;如果相等返回0;如果第一個范圍中的點位于第二個范圍中的點之后,返回1
如:
Hello world!
代碼:
var p = document.getElementById("p1"); var range1 = document.createRange(); var range2 = document.createRange(); range1.selectNodeContents(p); range2.selectNodeContents(p); range2.setEndBefore(p.lastChild); console.log(range1.toString()); //Hello world! console.log(range2.toString()); //Hello console.log(range1.compareBoundaryPoints(Range.START_TO_START, range2)); //0 console.log(range1.compareBoundaryPoints(Range.END_TO_END, range2)); //1
又如:
代碼:
var list = document.querySelector("#list"); var range1 = document.createRange(); var range2 = document.createRange(); range1.selectNodeContents(list); range1.setStartAfter(list.firstChild.nextSibling); range1.setEndBefore(list.lastChild.previousSibling); range2.selectNodeContents(list); console.log(range1.compareBoundaryPoints(Range.START_TO_START, range2)); //1 console.log(range1.compareBoundaryPoints(Range.END_TO_END, range2)); //-1 console.log(range1.compareBoundaryPoints(Range.START_TO_END, range2)); //1 注意這里是range1的END與range2的start對比; console.log(range1.compareBoundaryPoints(Range.END_TO_START, range2)); //-1 注意這里是range1的START與range2的END對比;復制DOM范圍 cloneRange()方法復制范圍;
var newRange = range.cloneRange();清理DOM范圍 detach()方法清理范圍;
range.detach(); range = null;
上面的是從文檔中分離范圍;下面的是解除引用。
下節(jié)再討論IE8及更早版本中的范圍
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/78426.html
摘要:和級分為許多模塊,分別描述了的某個非常具體的子集。這些模塊主要有核心視圖事件樣式遍歷和范圍以及。另外還有方法和方法框架的變化框架和內(nèi)嵌框架分別用和表示,它們在級中都有一個新屬性這個屬性包含一個指針,指向表示框架內(nèi)容的文檔對象。 DOM2和DOM3級分為許多模塊,分別描述了DOM的某個非常具體的子集。這些模塊主要有核心(Core)、視圖(Views)、事件(Events)、樣式(Styl...
摘要:級遍歷和范圍模塊定義了兩個用于輔助完成順序遍歷結(jié)構的類型和這兩個類型能夠基于給定的起點對結(jié)構執(zhí)行深度優(yōu)先的遍歷操作。其中的屬性,表示任何遍歷方法在上一次遍歷中返回的接待你。通過設置這個屬性也可以修改遍歷繼續(xù)進行的節(jié)點。 DOM2級遍歷和范圍模塊定義了兩個用于輔助完成順序遍歷DOM結(jié)構的類型:NodeIterator和TreeWalker;這兩個類型能夠基于給定的起點對DOM結(jié)構執(zhí)行深度...
摘要:如計算的樣式方法和屬性前者是增強了,這個方法接收兩個參數(shù)計算樣式的元素以及一個偽元素字符串如。操作表樣式類型表示的是樣式表,包括元素包含的樣式表和在元素中定義的樣式表。 層次:訪問style對象: style對象是CSSStyleDeclaration的實例; getComputedStyle方法也返回CSSStyleDeclaration的實例; 訪問樣式表: 元素包含的樣式表...
摘要:如計算的樣式方法和屬性前者是增強了,這個方法接收兩個參數(shù)計算樣式的元素以及一個偽元素字符串如。操作表樣式類型表示的是樣式表,包括元素包含的樣式表和在元素中定義的樣式表。 層次:訪問style對象: style對象是CSSStyleDeclaration的實例; getComputedStyle方法也返回CSSStyleDeclaration的實例; 訪問樣式表: 元素包含的樣式表...
摘要:擴展選擇符的核心是兩個方法和。目前已完全支持的瀏覽器有和。在寫模式下,會根據(jù)指定的字符串創(chuàng)建新的子樹,然后用這個子樹完全替換調(diào)用元素。在刪除帶有事件處理程序或引用了其他對象子樹時,就有可能導致內(nèi)存占用問題。刪除集合中指定位置的規(guī)則。 DOM擴展 選擇符API Selectors API Level 1 的核心是兩個方法:querySelector()和querySelectorAll(...
閱讀 3773·2021-09-22 15:17
閱讀 1959·2021-09-22 14:59
閱讀 2357·2020-12-03 17:00
閱讀 3222·2019-08-30 15:55
閱讀 495·2019-08-30 11:23
閱讀 3496·2019-08-29 13:56
閱讀 528·2019-08-29 12:54
閱讀 2266·2019-08-29 12:49