Range对象

本文详细介绍了DOM中的Range对象,包括其属性、方法,如定位、编辑等,以及在不同浏览器下的兼容性处理。通过示例展示了如何使用Range对象进行文本选择、删除、克隆和插入等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Range对象

属性

属性值说明
Range.collapsed用于判断Range对象所代表的区域的开始点与结束点是否处于相同的位置,如果相同该属性值返回true
Range.commonAncestorContainer用于返回Range对象所代表的区域位于什么节点之中,该属性值为包含了该区域的最低层节点(一个节点可能是一个元素,也可能是一段完整文字)的节点
Range.endContainer用于返回Range对象所代表的区域的终点位于什么节点之中,该属性值为包含了该区域终点的最底层节点
Range.endOffset用于返回Range对象所代表的区域的终点与包含该终点的节点的起点之间的距离
Range.startContainer用于返回Range对象所代表的区域的起点位于什么节点之中,该属性值为包含了该区域起点的最底层节点
Range.startOffset用于返回Range对象所代表的区域的起点与包含该起点的节点的起点之间的距离

方法

1、定位方法
方法说明
Range.setStart()用于将某个节点中的某处位置指定为Range对象所代表区域的起点位置
Range.setEnd()用于将某个节点中的某处位置指定Range对象所代表区域的结束位置
Range.setStartBefore()用于将某个节点的起点位置指定为Range对象所代表区域的起点位置
Range.setStartAfter()用于将某个节点的终点位置指定为Range对象所代表区域的起点位置
Range.setEndBefore()用于将某个节点的起点位置指定为Range对象所代表区域的终点位置
Range.setEndAfter()用于将某个节点的终点位置指定为Range对象所代表区域的终点位置
Range.selectNode()用于将Range对象的起点指定为某个节点的起点,将Range对象的终点指定为该节点的终点,使Range对象所代表的区域中包含该节点Range
Range.selectNodeContents()用于将Range对象的起点指定为某个节点中的所有内容的起点,将Range对象的终点指定为该节点所有内容的终点,使Range对象所代表的区域中包含该节点的所有内容
Range.collapse()向指定端点折叠该Range
2、编辑方法
方法说明
Range.cloneContents()用于在页面上追加一段HTML代码,并且将Range对象所代表区域中的HTML代码克隆到被追加的html代码中
Range.deleteContents()用于将Range对象中所包含的内容从页面中删除
Range.extractContents()用于将Range对象所代表区域中的html代码克隆到一个DocumentFragment对象中,然后从页面中删除这段HTML代码
Range.insertNode()用于将指定的节点插入到某个Range对象所代表的区域中,插入位置为Range对象所代表区域的起点位置
Range.surroundContents()将 Range 的内容移动到一个新的节点中
3、其他方法
方法说明
Range.compareBoundaryPoints()比较两个 Range 的端点。
Range.cloneRange()返回拥有和原 Range 相同端点的克隆 Range 对象。
Range.detach()从使用状态释放 Range,此方法用于改善性能
Range.toString()把Range内容作为字符串返回
4、Gecko方法

在这里解释Mozilla独有的,在W3C DOM标准里没有的 Range方法

方法说明
Range.compareNode()返回常量,表示node是否在range的前、后、中、外
Range.comparePoint()返回-1、0、1,分别表示指定点在range的前、中、后
Range.createContextualFragment()解析指定字符串(XML或HTML),并返回document fragment
Range.intersectsNode()返回boolean值,表示指定Node是否横断Range
Range.isPointInRange()返回boolean值,表示指定点是否在range中

document.selectiondocument.getSelection()/window.getSelection()分别为IEw3c浏览器 创建selection对象
document.createTextRange()document.createRange()分别为IE和w3c浏览器创建range对象
document.selection.createRange()window.getSelection().getRangeAt(0)是从selection对象获得range对象

标准dom是从window中获取selection对象,而ie是从document对象中获取。
标准dom range对象(以下称dom rang)和ieTextRange对象(以下称TextRange),在操作模式上有很大区别,可以说domrange是基于dom结构控制的,TextRange是基于文本节点字节控制的

二、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)

function getRange(selection) {
    if (selection.getRangeAt) {
        return selection.getRangeAt(0);
    } else { //不支持getRangeAt的情况
        var range = document.createRange();
        range.setStart(selection.anchorNode, selection.anchorOffset);
        range.setEnd(selection.focusNode, selection.focusOffset);
        return range;
    }
}
getRangeAt()

方法有一个参数index,代表该Range对象的序列号;我们可以通过Selection对象的rangeCount参数的值判断用户是否选取了内容;

<h3>selection对象与range对象的使用实例</h3>
 <input type="button" value="点击我" onclick="rangeTest()"/>
 <div id="showRange"></div>
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;
    }
}

上面的rangeObj代表一个Range对象,该方法使用一个参数,代表页面中的一个节点。

selectNode()

Range对象的selectNode方法用于将Range对象的起点指定为某个节点的起点,将Range对象的终点指定为该节点的终点,使Range对象所代表的区域中包含该节点
rangeObj.selectNode(node);

selectNodeContents()

用于将Range对象的起点指定为某个节点中的所有内容的起点,将Range对象的终点指定为该节点所有内容的终点,使Range对象所代表的区域中包含该节点的所有内容
rangeObj.selectNodeContents(node)

deleteContents()

用于将Range对象中所包含的内容从页面中删除
rangeObj.deleteContents()

<div id="div" style="background-color:#e0a0b0;width:300px;height:50px;">元素中的内容</div>
<button onclick="deleteRangeContents(true)">删除内容</button>
<button onclick="deleteRangeContents(false)">删除元素</button>
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();
    }
}
setStart()

用于将某个节点中的某处位置指定为Range对象所代表区域的起点位置
rangeObj.setStart(node,curIndex)
该setStart方法使用2个参数,第一个参数node代表一个节点,第二个参数是一个数字,当第一个参数 node所代表的节点是一个内容为一段文字的文字节点时,该参数值用于指定将第几个文字的结束位置作为Range对象所代表的区域的起点位置;当第一个参 数node所代表的节点中包括其他子节点时,该参数值用于将第几个子节点的结束位置指定为Range对象所代表的区域的起点位置;

setEnd()

用于将某个节点中的某处位置指定Range对象所代表区域的结束位置
rangeObj.setEnd(node,curIndex)

该方法中的2个参数的含义如setStart方法中参数的含义相同;只不过一个是起点位置,另一个是结束位置;

<div id="myDiv">这段文字中第三个文字到第十个文字将被删除掉</div>
 <button onclick="DeleteChar()">删除文字</button>
    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();
    }
setStartBefore()

用于将某个节点的起点位置指定为Range对象所代表区域的起点位置
rangeObj.setStartBefore(node)

setStartAfter()

用于将某个节点的终点位置指定为Range对象所代表区域的起点位置
rangeObj.setStartAfter(node)

setEndBefore()

用于将某个节点的起点位置指定为Range对象所代表区域的终点位置
rangeObj.setEndBefore(node)

setEndAfter()

用于将某个节点的终点位置指定为Range对象所代表区域的终点位置
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>
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();
    }
}
cloneRange()

Range对象的cloneRange方法用于对当前的Range对象进行复制,该方法返回复制的Range对象
var rangeClone = rangeObj.cloneRange()

<div id="test">aaaa</div>
<button onclick="cloneARange()">克隆Range对象</button> 
function cloneARange() {
    var testObj = document.getElementById("test");
    var rangeObj = document.createRange();
    rangeObj.selectNodeContents(testObj);
    var rangeClone = rangeObj.cloneRange();
    alert(rangeClone);
}
cloneContents()

该方法用于在页面上追加一段HTML代码,并且将Range对象所代表区域中的HTML代码克隆到被追加的html代码中
var html = rangeObj.cloneContents()

该方法不使用任何参数,该方法返回一个DocumentFragment对象,该对象为一个容器元素,当需要追加,删除,修改或查找页面上的元素,该对象变得非常有用;

<div id="div">实例文字<br/>
    <button onclick="cloneDivContent()">克隆</button>
</div>
function cloneDivContent() {
    var div = document.getElementById("div");
    var rangeObj = document.createRange();
    rangeObj.selectNodeContents(div);
    var documentFragment = rangeObj.cloneContents();
    div.appendChild(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>
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);
}
insertNode()

该方法用于将指定的节点插入到某个Range对象所代表的区域中,插入位置为Range对象所代表区域的起点位置,如果该节点已经存在于页面中,该节点将被移动到Range对象代表的区域的起点处。
rangeObj.insertNode(node)

<div onmouseup="MoveButton()" style="width:400px;height:100px;background-color:red">aaaaaaaaabbbbbb</div>
<button id="button">按钮</button>
function MoveButton() {
    var button = document.getElementById("button");
    var selection = document.getSelection();
    if(selection.rangeCount > 0) {
        var range = selection.getRangeAt(0);
        range.insertNode(button);
    }
}

三、TextRange对象

TextRange对象主要使用以下方法控制区域的选择
1、moveStart
2、moveEnd
3、move
这三个函数使用相同的参数语法:fn(sUnit [, iCount])
第一个参数是指移动的单位,可以使用的参数:character(字符)、word(词)、sentence(段落)、textedit(整个编辑区)
第二个参数指移动的数量单位,负数向所在位置之前移动,正数向所在位置之后移动。
在实际开发中一般使用character,其他几个参数在中文环境和html编辑时,和预想位置有偏差。

例1:TextRange选择光标前4个字符
var rg=document.selection.createRange(); 
rg.moveStart("character",-4); 
rg.select();//显式选择文本区域,不调用此函数也可以获得选择的内容 
var text=rg.text;//获得选择的文本 
var htmlText=rg.htmlText;//获得选择文本的html代码 

注:用rg.htmlText获得选择文本的html代码,但获得结果不尽人意,
如:<b>aaaa</b>bb ,当选择aabb段时,.htmlTex返回的是<b>aa</b>bb而不是aa</b>bb

dom range对象选择区域主要以dom节点为为坐标,所有边界移动和区域选择函数都是以dom节点为参照的.setEnd()setStart()是控制范围的前边界点和后边界点位置的函数,有两个参数,第一个参数是dom节点,第二个参数是偏移量,这个参数和TextRange.move中不同,是相对于dom节点的偏移量。

如:有文字节点node1 nodeValue是aaabbbccc,setStart(node1,3)则设置开始位置在字符a、b之间。那如何像例1一样选择光标前4个字符呢,这需要了解dom range对象的几个属性:

  • endContainer 包含范围的结束点的 dom节点。
  • endOffset endContainer 中的结束点位置。
  • startContainer 包含范围的开始点的 dom节点。
  • startOffset startContainer 中的开始点位置。
例2:dom range选择光标前4个字符
var rg=window.getSelection().getRangeAt(0); 
rg.setStart(rg.startContainer,rg.startOffset-4);//获得当前range strat所在节点和偏移量,计算后作为参数 
//在调用setStart后即显式选择,与TextRange不同 
var text=rg.toString();//获得选择文本 
rg.collapse(false);//collapse函数与TextRange.collapse相同 
<div id="ifram_div"></div>
window.onload=function(){
    var iframeContent="";
    var divContent="";
    var divChange=false;
    var iframeChange=false;
    var $=function(s){return document.getElementById(s);}
    $("ifram_div").innerHTML+='<div id="infoIframe">iframe</div><iframe id="youretextarea" style="height:200px;width:99%;" class="_editbox"></iframe>';
    var fw=$("youretextarea").contentWindow;
    var f=fw.document;
    f.designMode = 'On';
    f.contentEditable = true;
    f.open();
    f.writeln('<html><style>p{margin:0px;padding:0px;}body{margin:0px;padding:0px;font:16/18px Arial;}</style><body><b>aaaa</b><u>bbbb</u>cccddd</body></html>');
    f.close();
    if(f.attachEvent){
        f.attachEvent("onkeyup",fun1);
    }else{
        fw.addEventListener("keyup",fun1,true);
    }
    function fun1(){
        if(f.selection){
            var rg=f.selection.createRange();
            rg.moveStart("character",-4);
//rg.select();//显式选择文本区域,不调用此函数也可以获得选择的内容
            var text=rg.text;//获得选择的文本
            var htmlText=rg.htmlText;//获得选择文本的html代码
            alert(text);
        }else{
            var rg=fw.getSelection().getRangeAt(0);
            rg.setStart(rg.startContainer,rg.startOffset-4);//获得当前range strat所在节点和偏移量,计算后作为参数
//在调用setStart后即显式选择,与TextRange不同
            var text=rg.toString();//获得选择文本
            rg.collapse(false);//collapse函数与TextRange.collapse相同
            alert(text);
        }
    }
}
例3:获得用户所选内容
var userSelection;
if (window.getSelection) { //现代浏览器
    userSelection = window.getSelection();
} else if (document.selection) { //IE浏览器 考虑到Opera,应该放在后面
    userSelection = document.selection.createRange();
}
alert(userSelection)
var selectedText = userSelection;
if (userSelection.text) {
    selectedText = userSelection.text;
}

四、兼容

RangeTextRange
cloneRange()duplicate()
setStart()moveStart()
setEnd()moveEnd()
selectNodeContents()moveToElementText()
toString()text
compareBoundaryPoints()compareEndPoints()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值