一:Range對象的概念
Range對象代表頁面上一段連續(xù)的區(qū)域草穆,通過Range對象可以獲取或者修改頁面上任何區(qū)域的內(nèi)容乙帮。也可以通過Range的方法進(jìn)行復(fù)制和移動頁面任何區(qū)域的元素挨下。
在Js的document文檔中有一個方法用來創(chuàng)建一個Range對象步淹,代碼如下:
var range = document.createRange();
在html5中客们,每一個瀏覽器窗口都會有一個selection對象,代表用戶鼠標(biāo)在頁面中所選取的區(qū)域牺六,(注意:經(jīng)過測試IE9以下的瀏覽器不支持Selection對象), 可以通過如下語句創(chuàng)建selection對象颤枪;
var selection = document.getSelection();
或者
var selection = window.getSelection();
每一個selection對象都有一個或者多個Range對象,每一個range對象代表用戶鼠標(biāo)所選取范圍內(nèi)的一段連續(xù)區(qū)域淑际,在firefox中畏纲,可以通過ctrl鍵可以選取多個連續(xù)的區(qū)域,因此在firefox中一個selection對象有多個range對象春缕,在其他瀏覽器中盗胀,用戶只能選取一段連續(xù)的區(qū)域,因此只有一個range對象锄贼。
可以通過selection對象的getRangeAt方法來獲取selection對象的某個Range對象票灰,如下:
getRangeAt方法有一個參數(shù)index,代表該Range對象的序列號;我們可以通過Selection對象的rangeCount參數(shù)的值判斷用戶是否選取了內(nèi)容屑迂;
1.當(dāng)用戶沒有按下鼠標(biāo)時候浸策,該參數(shù)的值為0.
2.當(dāng)用戶按下鼠標(biāo)的時候,該參數(shù)值為1.
3.當(dāng)用戶使用鼠標(biāo)同時按住ctrl鍵時選取了一個或者多個區(qū)域時候屈糊,該參數(shù)值代表用戶選取區(qū)域的數(shù)量的榛。
4.當(dāng)用戶取消區(qū)域的選取時,該屬性值為1逻锐,代表頁面上存在一個空的Range對象夫晌;
測試代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<script>
function rangeTest() {
var html,
showRangeDiv = document.getElementById("showRange"),
selection = document.getSelection();
if(selection.rangeCount > 0) {
html = "你選取了" + selection.rangeCount + "段內(nèi)容<br/>";
for(var i = 0; i < selection.rangeCount; i++) {
var range = selection.getRangeAt(i);
html += "第" + (i + 1) + "段內(nèi)容為:" + range + "<br/>";
}
showRangeDiv.innerHTML = html;
}
}
</script>
<h3>selection對象與range對象的使用實例</h3>
<input type="button" value="點擊我" onclick="rangeTest()"/>
<div id="showRange"></div>
</body>
</html>
效果:
二:Range對象的屬性和方法
(1)屬性
startContainer
包含“起點”的節(jié)點∶劣眨“包含”的意思是起點所屬的節(jié)點晓淀。
endContainer
包含“結(jié)束點”的節(jié)點
startOffset
“起點”在startContainer中的偏移量。
如果startContainer是文本節(jié)點盏档、注釋節(jié)點或CDATA節(jié)點凶掰,則返回“起點”在startContainer中字符偏移量。
如果startContainer是元素節(jié)點蜈亩,則返回“起點”在startContainer.childNodes中的次序懦窘。
<p id="p1"><span>span</span><b id="b1">Hello</b> World</p>
<script type="text/javascript">
var oP1 = document.getElementById('p1') ;
var oB1 = document.getElementById('b1');
var oRange = document.createRange();
oRange.setStart(oB1.firstChild, 2); // 設(shè)置range的“起點” oRange.setEnd(oP1.lastChild, 3); // 設(shè)置range的“結(jié)束點” alert(oRange.startOffset); // 2,可看到“起點”在<b id="b1">Hello</b>應(yīng)是第三個字符稚配。
alert(oRange.startContainer); // 元素oB1.firstChild畅涂,文本節(jié)點</script>
collapsed:
起點和結(jié)束點在一起時為true;Range對象為空(剛createRange()時)也為true道川。
commonAncestorContainer
第一個包含Range的節(jié)點午衰,同時包含起點和結(jié)束點。
(2)定位(設(shè)置“起點”和“結(jié)束點”)的一些方法
setStart(node, offset)和setEnd(node, offset)
setStart:設(shè)置起點的位置冒萄,node是對startContainer的引用臊岸,偏移則是startOffset;
setEnd:設(shè)置結(jié)束點的位置尊流,node是對endContainer的引用帅戒,偏移則是startOffset;
代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>range3</title>
<script>
function deleteChar() {
var div = document.getElementById("myDiv");
var textNode = div.firstChild;
var rangeObj = document.createRange();
rangeObj.setStart(textNode,1);
rangeObj.setEnd(textNode,4);
rangeObj.deleteContents();
}
</script>
</head>
<body>
<div id="myDiv" style="color:red">這段文字是用來刪除的</div>
<button onclick="deleteChar()">刪除文字</button>
</body>
</html>
setStartBefore(referenceNode)奠旺、setStartAfter(referenceNode)
setEndBefore(referenceNode)蜘澜、setEndAfter(referenceNode)
setStartBefore:將“起點”設(shè)置到referenceNode前
setStartAfter:將“起點”設(shè)置到referenceNode后
setEndBefore:將“結(jié)束點”設(shè)置到referenceNode前
setEndAfter:將“結(jié)束點”設(shè)置到referenceNode后
注意:使用這四個方法設(shè)置的“起點”或“結(jié)束點”的父節(jié)點與referenceNode的父節(jié)點是同一個元素。
代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="application/javascript">
function delrow(){
var table=document.getElementById("mytable");
if(table.rows.length>0){
var row=table.rows[0];
var rangeObj=document.createRange();
rangeObj.setStartBefore(row);
rangeObj.setEndAfter(row);
rangeObj.deleteContents();
}
}
</script>
</head>
<body>
<table id="mytable" border="1">
<tr>
<td>內(nèi)容1</td>
<td>內(nèi)容2</td>
</tr>
<tr>
<td>內(nèi)容3</td>
<td>內(nèi)容4</td>
</tr>
</table>
<button onclick="delrow()">刪除第一行</button>
</body>
</html>
selectNode(referenceNode)和selectNodeContents(referenceNode)
selectNode:設(shè)置Range的范圍响疚,包括referenceNode和它的所有后代(子孫)節(jié)點。
selectNodeContents:設(shè)置Range的范圍瞪醋,包括它的所有后代節(jié)點忿晕。
二者的區(qū)別:
(3)修改范圍的方法
cloneRange()
cloneRange()方法將返回一個當(dāng)前Range的副本,它也是Range對象银受。
注意它和cloneContents()的區(qū)別在于返回值不同践盼,一個是HTML片段鸦采,一個是Range對象 。代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<p id="p">這里是隨便書寫的內(nèi)容</p>
<button onclick="cloneRange()">克隆</button>
</body>
<script>
function cloneRange() {
var rangeObj = document.createRange();
rangeObj.selectNodeContents(document.getElementById("p"));
var rangeClone = rangeObj.cloneRange();
alert(rangeClone.toString());
}
</script>
</html>
cloneContents()
可以克隆選中Range的fragment并返回改fragment咕幻。這個方法類似extractContents()渔伯,但不是刪除,而是克隆肄程。代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<p id="p">這里是隨便書寫的內(nèi)容</p>
<button onclick="cloneContents()">克隆</button>
</body>
<script>
function cloneContents() {
var rangeObj = document.createRange();
rangeObj.selectNodeContents(document.getElementById("p"));
var rangeClone = rangeObj.cloneContents();
alert(rangeClone.toString());
}
</script>
</html>
deleteContents()
從Dom中刪除Range選中的fragment锣吼。注意該函數(shù)沒有返回值(實際上為undefined)。
代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<p id="p">這里是隨便書寫的內(nèi)容</p>
<button onclick="delRange()">刪除</button>
</body>
<script>
function delRange() {
var rangeObj = document.createRange();
rangeObj.selectNodeContents(document.getElementById("p"));
var rangeClone = rangeObj.deleteContents();
}
</script>
</html>
extractContents()
將選中的Range從DOM樹中移到一個fragment中蓝厌,并返回此fragment玄叠。代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<div id="srcDiv" style="background-color:aquamarine;width:300px;height:50px;">你好嗎?</div>
<div id="distDiv" style="background-color:bisque;width:300px;height:50px"></div>
<button onclick="moveContent()">移動元素</button>
</body>
<script>
function moveContent() {
var srcDiv = document.getElementById("srcDiv");
var distDiv = document.getElementById("distDiv");
var rangeObj = document.createRange();
rangeObj.selectNodeContents(srcDiv);
var docFrangMent = rangeObj.extractContents();
distDiv.appendChild(docFrangMent);
}
</script>
</html>
insertNode
insertNode方法可以插入一個節(jié)點到Range中拓提,注意會插入到Range的“起點”读恃。代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>meter</title>
</head>
<body>
<p id="p1"><b>Hello</b> World</p>
</body>
<script>
var oP1 = document.getElementById("p1");
var oHello = oP1.firstChild.firstChild;
var oWorld = oP1.lastChild;
var oRange = document.createRange();
var oSpan = document.createElement("span");
oSpan.appendChild(document.createTextNode("Inserted text"));
oRange.setStart(oHello, 2);
oRange.setEnd(oWorld, 3);
oRange.insertNode(oSpan);
</script>
</html>
compareBoundaryPoints()
var compare = comparerange.compareBoundaryPoints(how, sourceRange);
compare:返回1, 0, -1.(0為相等,1為時代态,comparerange在sourceRange之后寺惫,-1為comparerange在sourceRange之前)。
how:比較哪些邊界點蹦疑,為常數(shù)西雀。
Range.START_TO_START - 比較兩個 Range 節(jié)點的開始點
Range.END_TO_END - 比較兩個 Range 節(jié)點的結(jié)束點
Range.START_TO_END - 用 sourceRange 的開始點與當(dāng)前范圍的結(jié)束點比較
Range.END_TO_START - 用 sourceRange 的結(jié)束點與當(dāng)前范圍的開始點比較
sourceRange:個Range對象的邊界。
detach()
雖然GC(垃圾收集器)會將其收集必尼,但用detach()釋放range對象是一個好習(xí)慣蒋搜。語法為:oRange.detach();
toString()
返回該范圍表示的文檔區(qū)域的純文本內(nèi)容,不包含任何標(biāo)簽;
謝謝觀看判莉,希望對您有幫助豆挽。一起學(xué)前端一起成長!(__) 嘻嘻……