HTML5中的Range物件的研究

龍恩0707發表於2015-06-27

一:Range物件的概念

 Range物件代表頁面上的一段連續區域,通過Range物件,可以獲取或修改頁面上的任何區域,可以通過如下建立一個空的Range物件,如下:

      var  range = document.createRange();

在html5中,每一個瀏覽器視窗及每一個視窗中都有一個selection物件,代表使用者滑鼠在頁面中所選取的區域,(注意:經過測試IE9以下的瀏覽器不支援Selection物件), 可以通過如下語句建立selection物件;

   var  selection = document.getSelection();     或者

   var  selection  = window.getSelection();

每一個selection物件都有一個或者多個Range物件,每一個range物件代表使用者滑鼠所選取範圍內的一段連續區域,在firefox中,可以通過ctrl鍵可以選取多個連續的區域,因此在firefox中一個selection物件有多個range物件,在其他瀏覽器中,使用者只能選取一段連續的區域,因此只有一個range物件。

可以通過selection物件的getRangeAt方法來獲取selection物件的某個Range物件,如下:

   var range = document.getSelection().getRangeAt(index);

getRangeAt方法有一個引數index,代表該Range物件的序列號;我們可以通過Selection物件的rangeCount引數的值判斷使用者是否選取了內容;

  1. 當使用者沒有按下滑鼠時候,該引數的值為0.
  2. 當使用者按下滑鼠的時候,該引數值為1.
  3. 當使用者使用滑鼠同時按住ctrl鍵時選取了一個或者多個區域時候,該引數值代表使用者選取區域的數量。
  4. 當使用者取消區域的選取時,該屬性值為1,代表頁面上存在一個空的Range物件;

如下程式碼測試:

<h3>selection物件與range物件的使用例項</h3>
<input type="button" value="點選我" onclick="rangeTest()"/>
<div id="showRange"></div>

JS程式碼如下:

<script>
   function rangeTest() {
        var  html,
        showRangeDiv = document.getElementById("showRange"),
         selection = document.getSelection();
        if(selection.rangeCount > 0) {
            html = "你選取了" + selection.rangeCount + "段內容<br/>";
            for(var i = 0; i < selection.rangeCount; i++) {
                var range = selection.getRangeAt(i);
                html += "第" + (i + 1) + "段內容為:" + range + "<br/>";
            }
            showRangeDiv.innerHTML = html;
        }
    }
</script>

如上程式碼,當使用者選取一段文字後,點選按鈕,會顯示選取的文字,如下在firefox下效果:

在chrome瀏覽器下如下所示:

二:Range物件的屬性和方法

屬性如下:

collapsed(boolean) :  用於判斷Range物件所代表的區域的開始點與結束點是否處於相同的位置,如果相同該屬性值返回true;

commonAncestorContainer(node):  用於返回Range物件所代表的區域位於什麼節點之中,該屬性值為包含了該區域的最低層節點(一個節點可能是一個元素,也可能是一段完整文字)的節點。

endContainer(node):  用於返回Range物件所代表的區域的終點位於什麼節點之中,該屬性值為包含了該區域終點的最底層節點。

endOffset(整數值型別)用於返回Range物件所代表的區域的終點與包含該終點的節點的起點之間的距離。

startContainer(node):   用於返回Range物件所代表的區域的起點位於什麼節點之中,該屬性值為包含了該區域起點的最底層節點。

startOffset(整數值型別)用於返回Range物件所代表的區域的起點與包含該起點的節點的起點之間的距離。

下面還有很多方法,方法的含義比較難理解,我這邊也是看到書上這麼寫的,順便自己做了demo試了下,理解下其含義。以後需要使用到的可以看一下即可;

selectNode方法:Range物件的selectNode方法用於將Range物件的起點指定為某個節點的起點,將Range物件的終點指定為該節點的終點,使Range物件所代表的區域中包含該節點。使用方法如下:

rangeObj.selectNode(node);

上面的rangeObj代表一個Range物件,該方法使用一個引數,代表頁面中的一個節點。

selectNodeContents方法:用於將Range物件的起點指定為某個節點中的所有內容的起點,將Range物件的終點指定為該節點所有內容的終點,使Range物件所代表的區域中包含該節點的所有內容。使用方法如下:

rangeObj.selectNodeContents(node);

含義如上所示;

deleteContents方法:用於將Range物件中所包含的內容從頁面中刪除,使用方法如下所示:

rangeObj.deleteContents();

我們下面來做一個demo,來理解下上面的三個方法;如下程式碼:

<div id="div" style="background-color:#e0a0b0;width:300px;height:50px;">元素中的內容</div>
<button onclick="deleteRangeContents(true)">刪除內容</button>
<button onclick="deleteRangeContents(false)">刪除元素</button>

頁面上顯示如下:

JS程式碼如下:

<script>
    function deleteRangeContents(flag) {
        var div = document.getElementById("div");
        var rangeObj = document.createRange();
        if(flag) {
                         // selectNodeContents指選中Range物件中的所有內容  進行刪除掉
            rangeObj.selectNodeContents(div);
            rangeObj.deleteContents();
        }else {
            rangeObj.selectNode(div);
            rangeObj.deleteContents();
        }
    }
</script>

當程式碼執行完document.createRange();時候,我們看看rangeObj物件的值是多少,

當點選刪除內容的時候,就把相應的內容刪掉;如下所示:

程式碼執行到下面的,rangeObj物件的值變成如下:

當我們點選刪除元素的按鈕時候,如下所示:

此時rangeObj物件變成如下:

setStart方法 用於將某個節點中的某處位置指定為Range物件所代表區域的起點位置,使用方法如下:

rangeObj.setStart(node,curIndex);

如上程式碼rangeObj代表一個Range物件,該setStart方法使用2個引數,第一個引數node代表一個節點,第二個引數是一個數字,當第一個引數node所代表的節點是一個內容為一段文字的文位元組點時,該引數值用於指定將第幾個文字的結束位置作為Range物件所代表的區域的起點位置;當第一個引數node所代表的節點中包括其他子節點時,該引數值用於將第幾個子節點的結束位置指定為Range物件所代表的區域的起點位置;

setEnd方法  用於將某個節點中的某處位置指定Range物件所代表區域的結束位置。使用方法如下所示:

rangeObj.setEnd(node,curIndex);

該方法中的2個引數的含義如setStart方法中引數的含義相同;只不過一個是起點位置,另一個是結束位置;

我們來看一個demo,來理解下上面的2個方法的含義;程式碼如下:

<div id="myDiv">這段文字中第三個文字到第十個文字將被刪除掉</div>
<button onclick="DeleteChar()">刪除文字</button>

JS程式碼如下:

<script>
    function DeleteChar(){
        var myDiv = document.getElementById("myDiv");
        var textNode = myDiv.firstChild;
        var rangeObj = document.createRange();
        rangeObj.setStart(textNode,2);
        rangeObj.setEnd(textNode,10);
        rangeObj.deleteContents();
    }
</script>

當我們點選刪除文字按鈕的時候,第3個到第10個文字被刪除掉~

setStartBefore方法:用於將某個節點的起點位置指定為Range物件所代表區域的起點位置。

setStartAfter方法: 用於將某個節點的終點位置指定為Range物件所代表區域的起點位置。

setEndBefore方法: 用於將某個節點的起點位置指定為Range物件所代表區域的終點位置。

setEndAfter方法:  用於將某個節點的終點位置指定為Range物件所代表區域的終點位置。

使用方法如下所示:

rangeObj.setStartBefore(node);

rangeObj.setStartAfter(node);

rangeObj.setEndBefore(node);

rangeObj.setEndAfter(node);

我們還是先來做一個demo,來理解下上面的四個方法;如下所示:

<table id="myTable" border = "1" cellspacing="0" cellpadding="0">
    <tr>
        <td>第一行第一列</td>
        <td>第一行第二列</td>
    </tr>
    <tr>
        <td>第二行第一列</td>
        <td>第二行第二列</td>
    </tr>
</table>
<button onclick="deleteFirstRow()">刪除第一行</button>

JS程式碼如下所示:

<script>
    function deleteFirstRow(){
        var myTable = document.getElementById("myTable");
        if(myTable.rows.length > 0){
            var row = myTable.rows[0];
            var rangeObj = document.createRange();
            rangeObj.setStartBefore(row);
            rangeObj.setEndAfter(row);
            rangeObj.deleteContents();
        }
    }
</script>

如上程式碼所示;使用者單擊 刪除第一行按鈕時候,表格的第一行將會被刪除掉;

cloneRange方法  Range物件的cloneRange方法用於對當前的Range物件進行復制,該方法返回複製的Range物件,該方法使用如下所示:

var rangeClone = rangeObj.cloneRange();

我們可以先來看看一個demo列子,如下所示:

<div id="test">aaaa</div>
<button onclick="cloneARange()">克隆Range物件</button> 

JS程式碼如下:

<script>
    function cloneARange() {
        var testObj = document.getElementById("test");
        var rangeObj = document.createRange();
        rangeObj.selectNodeContents(testObj);
        var rangeClone = rangeObj.cloneRange();
        alert(rangeClone);
    }
</script>

如下圖所示:

cloneContents方法  該方法用於在頁面上追加一段HTML程式碼,並且將Range物件所代表區域中的HTML程式碼克隆到被追加的html程式碼中;

使用方法如下所示:

var  html = rangeObj.cloneContents();

該方法不使用任何引數,該方法返回一個DocumentFragment物件,該物件為一個容器元素,當需要追加,刪除,修改或查詢頁面上的元素,該物件變得非常有用;

如下程式碼所示:

<div id="div">
    例項文字
    <br/>
    <button onclick="cloneDivContent()">克隆</button>
</div>

JS程式碼如下:

<script>
    function cloneDivContent() {
        var div = document.getElementById("div");
        var rangeObj = document.createRange();
        rangeObj.selectNodeContents(div);
        var documentFragment = rangeObj.cloneContents();
        div.appendChild(documentFragment);
    }
</script>

如上程式碼,使用者單擊頁面上的克隆按鈕後,將會把div元素中的內容克隆到div元素底部;我們再來看看documentFragment物件的屬性如下:

extractContents方法 用於將Range物件所代表區域中的html程式碼克隆到一個DocumentFragment物件中,然後從頁面中刪除這段HTML程式碼;

該方法使用方式如下:

var  documentFragment = rangeObj.extractContents();

該方法返回一個包含了Range物件所代表區域中的HTML程式碼的DocumentFragment物件。

如下程式碼所示:

<div id="srcDiv" style="width:300px;height:50px;background-color:red;">demo</div>
<div id="destDiv" style="width:300px;height:50px;background:blue;">demo2</div>
<button onclick = "moveContent()">移動元素內容</button>

JS程式碼如下:

<script>
    function moveContent() {
        var srcDiv = document.getElementById("srcDiv");
        var destDiv = document.getElementById("destDiv");
        var rangeObj = document.createRange();
        rangeObj.selectNodeContents(srcDiv);
        var documentFragment = rangeObj.extractContents();
        destDiv.appendChild(documentFragment);
    }
</script>

原頁面如下:

點選按鈕後變成如下:

insertNode方法: 該方法用於將指定的節點插入到某個Range物件所代表的區域中,插入位置為Range物件所代表區域的起點位置,如果該節點已經存在於頁面中,該節點將被移動到Range物件代表的區域的起點處。使用方法如下:

rangeObj.insertNode(node);

如下demo:

程式碼如下:

<div onmouseup="MoveButton()" style="width:400px;height:100px;background-color:red">aaaaaaaaabbbbbb</div>
<button id="button">按鈕</button>

JS程式碼如下:

<script>
    function MoveButton() {
        var button = document.getElementById("button");
        var selection = document.getSelection();
        if(selection.rangeCount > 0) {
            var range = selection.getRangeAt(0);
            range.insertNode(button);
        }
    }
</script>

頁面初始化的時候如下:

當在相應的地方按下鍵的時候,變成如下:

以上是一些基本知識點;為了下一篇文件上傳圖片需要使用到的知識,可以先了解下一些基本知識點~

相關文章