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