Dom中的范围

来源:互联网 发布:mac电池显示大叉 编辑:程序博客网 时间:2024/06/06 12:49

DOM2级在Document类型中定义了createRange()方法。在兼容DOM浏览器的浏览器中,这个方法属于document对象。使用hasFeature()或者直接检测该方法,都可以确定浏览器是否支持范围

var supportRange=document.implementation.hasFeature("Range","2.0");

如果浏览器支持范围,那么就可以使用createRange()来创建Dom范围

var range=document.createRange();
新创建的范围直接与创建它的文档关联在一起,不能用于其他文档。每个范围由一个Range类型的实例表示,这个实例拥有很多属性和方法

startContainer:包含范围起点的几点(即选区中第一个节点的父节点)

startOffset:范围在startOffset中起点的偏移量。如果startContainer是文本节点、注释节点或CDATA节点,那么startOffset就是范围起点之前跳过的字符数量。否则,startOffset就是范围中第一个子节点的索引

endContainer:包含范围终点的节点(即选区中最后一个节点的父节点)

endOffset:范围在endContainer中终点的偏移量

1 用DOM实现简单选择

要使用范围来选择文档中的一部分,最简的方式就是使用selectNode()或selectNodeContents(),这两个方法都接受一个参数,即一个DOM节点,然后使用该节点中的信息来填充范围。其中selectNode()方法选择整个节点,包括其子节点;而selectNodeContents()方法则只选择节点的子节点

在调用selectNode时,startContainer、endContainer都等于传入节点的父节点,startOffset属性等于给定节点在其父节点的childNodes集合中的索引。

<body><span style="white-space:pre"></span><p id="p">范围</p><script type="text/javascript">var p=document.getElementById("p");var range1=document.createRange();console.log(range1.startContainer);</script></body>
为了更精细地控制将那些节点包含在范围中,还可以使用下列方法

setStartBefore(refNode):将范围的起点设置在refNode之前,因此refNode就是范围选区中的第一个子节点,同时将startContainer属性设置为refNode.parentNode,将startOffset属性设置为refNode在父节点的childNodes集合中的索引

setStartAfter(refNode):将范围的起点设置在refNode之后,因此refNode就不在范围之内,其下一个同辈节点才是选区中的第一个子节点。同时将startContainer属性设置为refNode.parentNode,将startOffset属性设置为refNode在父节点的childNodes集合中的索引加1

setEndBefore(refNode):将范围的终点设置在refNode之前,,因此refNode就不在范围之内,其上一个同辈节点才是选区中的最后一个子节点,同时将endContainer属性设置为refNode.parentNode,将endOffset属性设置为refNode在父节点的childNodes集合中的索引

setEndAfter(refNode):将范围的终点设置在refNode之后,因此refNode就是范围选区中的最后一个子节点,同时将endContainer属性设置为refNode.parentNode,将endOffset属性设置为refNode在父节点的childNodes集合中的索引加1

2 用DOM范围实现复杂选区

要创建复杂的范围需要使用setStart()和setEnd()方法。这两个方法都接受两个参数:一个参照节点和一个偏移量。对setStart()来说,参照节点会变成startContainer,而偏移量会变成startOffset;对于setEnd(),参照节点会变成endContainer,而偏移量会变成endOffset。

<div id="con" style="height:100px;width:100px;border:1px solid red;"><p id="p1">hello <b>world</b></p></div>var p1=document.getElementById("p1");var helloNode=p1.firstChild;var worldNode=p1.lastChild.firstChild;var range2=document.createRange();range2.setStart(helloNode,2);range2.setEnd(worldNode,3);
在创建范围时,内部会为这个范围创建一个文档片段,范围所属的全部节点都被添加到了这个文档片段中。对于上面的例子,范围经过计算知道选区中缺少一个结束的</b>标签,因此就会在后台动态加载一个该标签。修改后的DOM如下所示

<p>hello <b>wor</b><b>ld</d></p>
利用deleteContents()可以从文档中删除范围所包含的内容 range2.deleteContents()

利用insertNode()方法可以向范围选区的开始处插入一个节点。

除了向范围内部插入内容之外,还可以环绕范围插入内容,此时就使用surroundContents()方法,这个方法接受一个参数,即环绕范围内容的节点。

<p id="p">范围</p>
var p=document.getElementById("p");var pText=p.firstChild;var range1=document.createRange();range1.selectNode(pText);var span=document.createElement("span");span.style.backgroundColor="yellow";range1.surroundContents(span);

执行结果就是“范围”被添加了黄色背景




0 0
原创粉丝点击