Javascript 标准 DOM Range 操作 (1)

createRange 方法

2 级 DOM 定义了一个 createRange() 方法,如果是按照 DOM 此标准的浏览器( IE 并不是支持此标准的,但是 IE 里的属性或方法却远比标准中的功能多得多),它属于 document 对象,所以创建一个 range 对象:

var oRange = document.createRange();

如果你要检测你的浏览器是否支持此标准 Range 对象,可以用 hasFeature() 方法来检测:

var supportsDOMRanges = document.implementation.hasFeature("Range", "2.0");
if (supportsDOMRange) {
	var oRange = document.createRange();
	//range code here
}

用 Range 对象进行简单的选择

最简单用 Range 进行选择,用 selectNode() 或者 selectNodeContents() 方法,这两个方法 只有 1 个接收参数, 1 个 DOM 节点。

selectNode() 方法选择全部节点,包括它的孩子,而 selectNodeContents() 选择的节点只是它的孩子:

<p id="p1"><b>Hello</b> World</p>
<script>
var oRange1 = document.createRange();
var oRange2 = document.createRange();
var oP1 = document.getElementById("p1");
oRange1.selectNode(oP1);
oRange2.selectNodeContents(oP1);
</script>

oRange1 和 oRange2 包含上面所说的两种方法,看了下面的示图相信你能很快明白这两个方法的区别:

range demo

当你创建了一个 Range 对象时, Range 实例会有以下的属性:

  • startContainer — 返回 Range 对象从何开始的节点对象(父节点的第一个节点)
  • startOffset — 返回 Range 开始的偏移量 (offset) 。
    • 如果 startContainer 是一个文本节点、注释节点、或者是 CDATA 节点;
    • 这个属性返回文本的偏移量,否则返回第一个节点的索引 (index) 。
  • endCOntainer — 返回 Range 对象最后一个节点对象(父节点的最后一个节点)
  • endOffset — 返回 Range 结束时的偏移量 (offset) 特性与 startOffset 相同。
  • commonAncestorContainer — 返回第一个包含该 Range 对象的节点。

注:这些属性均为只读属性 (read-only) , startOffset 和 endOffset 将在下文中有较详细的解释。

下面这段代码将说明这些属性,请在 Mozilla firefox 里运行(支持此标准的浏览器—— DOM 2 级, IE 里将无效):

<html>
 <head>
 <title>DOM Range Example</title>
 <script type="text/javascript">
 function useRanges() {
	 var oRange1 = document.createRange();
	 var oRange2 = document.createRange();
	 var oP1 = document.getElementById("p1");
	 oRange1.selectNode(oP1);
	 oRange2.selectNodeContents(oP1);
	 
	 document.getElementById("txtStartContainer1").value 
	    = oRange1.startContainer.tagName;
	 document.getElementById("txtStartOffset1").value = 
	    oRange1.startOffset;
	 document.getElementById("txtEndContainer1").value = 
	    oRange1.endContainer.tagName;
	 document.getElementById("txtEndOffset1").value = 
	    oRange1.endOffset;
	 document.getElementById("txtCommonAncestor1").value = 
	    oRange1.commonAncestorContainer.tagName;
	 document.getElementById("txtStartContainer2").value = 
	    oRange2.startContainer.tagName;
	 document.getElementById("txtStartOffset2").value = 
	    oRange2.startOffset;
	 document.getElementById("txtEndContainer2").value = 
	    oRange2.endContainer.tagName;
	 document.getElementById("txtEndOffset2").value = 
	    oRange2.endOffset;
	 document.getElementById("txtCommonAncestor2").value = 
	    oRange2.commonAncestorContainer.tagName;
}
 </script>
 </head>
 <body><p id="p1"><b>Hello</b> World</p>
 <input type="button" value="Use Ranges" onclick="useRanges()" /> 
 <table border="0">
 <tr>
 <td>
 <fieldset>
 <legend>oRange1</legend>
 Start Container: 
    <input type="text" id="txtStartContainer1" /><br />
 Start Offset: 
    <input type="text" id="txtStartOffset1" /><br />
 End Container: 
    <input type="text" id="txtEndContainer1" /><br />
 End Offset: 
    <input type="text" id="txtEndOffset1" /><br />
 Common Ancestor: 
    <input type="text" id="txtCommonAncestor1" /><br /> 
 </fieldset>
 </td>
 <td>
 <fieldset>
 <legend>oRange2</legend>
 Start Container: 
    <input type="text" id="txtStartContainer2" /><br />
 Start Offset: 
    <input type="text" id="txtStartOffset2" /><br />
 End Container: 
    <input type="text" id="txtEndContainer2" /><br />
 End Offset: 
    <input type="text" id="txtEndOffset2" /><br />
 Common Ancestor: 
    <input type="text" id="txtCommonAncestor2" /><br />
 </fieldset>
 </td>
 </tr>
 </table>
 </body>
</html>

上面的代码将不作注释了,有什么问题,在评论中留言。

Range 中还有一些其它的方法:

  • setStartBefore(node) — 设置 Range 的相对于 node 节点的起始位置
  • setStartAfter(node) — 同上
  • setEndBefore — 设置 Range 的相对于 node 节点的结束位置
  • setEndAfter — 同上

Comments