首页 > 代码库 > Notes: DOM Range

Notes: DOM Range

通过DOM范围可以选择文档中的某个区域,而不需考虑节点的界限,例如文本高亮的处理就可以使用范围来实现。

1、Range的创建

使用document的createRange来创建一个范围,该方法返回一个Range实例,该实例有很多属性和方法,如下所示:

startContainer:包含范围起点的节点

startOffset:范围起点在startContainer中的偏移量,既节点索引

endContainer:包含范围终点的节点

endOffset:范围终点在endContainer的偏移量,节点索引+1

检测浏览器是否支持范围

document.implementation.hasFeature(‘Range‘,‘2.0‘)  ORtypeof document.createRange === ‘function‘

创建范围

var range = document.createRange();
//由于IE8及以下浏览器不支持DOM Range,但是支持文本范围(document.body.createTextRange)
var range = document.body.createTextRange();

2、Range的实例方法

假设有一个HTML文档如下所示

<!DOCTYPE html><html><head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width">  <title>JS Bin</title></head><body>  <div class="outer" id="outer">    <div class="inner" id="inner1">hello world!</div>    <div class="inner" id="inner2"><span>你好吗</span></div>  </div></body></html>

选择文档的一部分,可以使用selectNode或者selectNodeContents方法,如下所示

var range = document.createRange();range.selectNode(inner1);console.log(range.startOffset);//1  因为空格被当作一个文本节点---------------------------------------------------var range = document.createRange();range.selectNodeContents(outer);console.log(range.endOffset);//5 
//IE8以下var range = document.body.createTextRange();range.findText("hello");console.log(range.text);//hellorange.moveToElementText(inner1);console.log(range.htmlText);

也可以使用setStartBefore、setStartAfter、setEndBefore、setEndAfter等方法来选择文档范围

var range = document.createRange();range.setStartBefore(inner1);range.setEndBefore(inner2);console.log(range.endOffset);//3

还可以使用setStart和setEnd来选择,这两个函数均需要两个参数,一个参照节点,一个偏移量,对于setStart来说,参照节点便是startContainer,而setEnd的参照节点是endContainer

var range = document.createRange();range.setStart(inner1,0);range.setEnd(inner1,inner1.childNodes.length);console.log(range.endOffset);//1
//IE8以下range.moveStart("word", 2); //起点移动2 个单词range.moveEnd("character", 1); //终点移动1 个字符-----------------------------------------"character":逐个字符地移动。"word":逐个单词(一系列非空格字符)地移动。"sentence":逐个句子(一系列以句号、问号或叹号结尾的字符)地移动。"textedit":移动到当前范围选区的开始或结束位置。

操作选区中内容

1、从文档中删除选区的内容deleteContents和extractContents,他们的区别就是后者会返回删除的文档片段,如下所示

var range = document.createRange();range.setStart(inner1.firstChild,0);range.setEnd(inner1.firstChild,5);//range.deleteContents();var fragment = range.extractContents();box.appendChild(fragment);

2、复制选区内容cloneContents,复制出来的只是范围中节点的副本,不是真实的节点

var range = document.createRange();range.setStart(outer,0);range.setEnd(outer,outer.childNodes.length);var fragment = range.cloneContents();box.appendChild(fragment);

3、向范围中插入内容insertNode或者surroundContents

var range = document.createRange();range.selectNodeContents(outer);var span = document.createElement(‘span‘);span.innerText = "我知道了";range.insertNode(span);//会在范围的开始处插入指定节点------------------------------------------------------------------var range = document.createRange();range.setStart(inner1.firstChild,0);range.setEnd(inner1.firstChild,5);var span = document.createElement(‘span‘);span.className = "red";range.surroundContents(span);
//ie8以下var range = document.body.createTextRange();range.findText("Hello");range.text = "Howdy";-------------------------------------range.pasteHTML("<em>Howdy</em>");//类似与range.surroundContents

4、复制Range和清理Range

复制range,使用cloneRange方法,该方法复制出来的是指定范围的副本;使用detach方法把范围从文档中分离,然后解除范围的引用

var range = document.createRange();range.setStart(inner1.firstChild,0);range.setEnd(inner1.firstChild,5);var rangeBak = range.cloneRange();var fragment = rangeBak.extractContents();box.appendChild(fragment);range.detach();range = null;

 

Notes: DOM Range