html5之Range對象詳解

一: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_selection.png

二: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ū)別:

range_selection.png

(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é)前端一起成長!(__) 嘻嘻……

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末券盅,一起剝皮案震驚了整個濱河市帮哈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锰镀,老刑警劉巖挟纱,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異抖誉,居然都是意外死亡任洞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門花鹅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來氧腰,“玉大人,你說我怎么就攤上這事」潘” “怎么了箩帚?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長黄痪。 經(jīng)常有香客問我紧帕,道長,這世上最難降的妖魔是什么桅打? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任是嗜,我火速辦了婚禮,結(jié)果婚禮上油额,老公的妹妹穿的比我還像新娘叠纷。我一直安慰自己,他們只是感情好潦嘶,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布涩嚣。 她就那樣靜靜地躺著,像睡著了一般掂僵。 火紅的嫁衣襯著肌膚如雪航厚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天锰蓬,我揣著相機(jī)與錄音幔睬,去河邊找鬼。 笑死芹扭,一個胖子當(dāng)著我的面吹牛麻顶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播舱卡,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼辅肾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了轮锥?” 一聲冷哼從身側(cè)響起矫钓,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎舍杜,沒想到半個月后新娜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡既绩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年概龄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饲握。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡旁钧,死狀恐怖吸重,靈堂內(nèi)的尸體忽然破棺而出互拾,到底是詐尸還是另有隱情歪今,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布颜矿,位于F島的核電站寄猩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏骑疆。R本人自食惡果不足惜田篇,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望箍铭。 院中可真熱鬧泊柬,春花似錦、人聲如沸诈火。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冷守。三九已至刀崖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拍摇,已是汗流浹背亮钦。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留充活,地道東北人蜂莉。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像混卵,于是被迫代替她去往敵國和親映穗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容