在网上查找Range相关资料时,发现都是残缺不全的,最后在W3C官方查找到一篇最为全面的介绍Range的文章,现将文章总结如下,希望对大家有所帮助。
Range的定义
当用户浏览一些页面时,经常使用鼠标选中一些文本,而JS中的Range对象,就是用来标识用户选中了哪些文本。
用户选中的文本,都是有起始和结束的,同样,我们可以用起始
和结束
两个边界点来生成一个Range对象,而边界点的定义是通过Node节点+偏移
的形式。
举个例子,当我们的网页是如下代码时,网页就会自动选择如图所示内容:
<body>
<h1>Title</h1>
<p>Blah xyz.</p>
</body>
<script>
//创建Range
let range = document.createRange();
//设置Range的起始和结束边界点
let startNode = document.getElementsByTagName('h1')[0].childNodes[0];
let endNode = document.getElementsByTagName('p')[0].childNodes[0];
range.setStart(startNode, 2);
range.setEnd(endNode, 1);
//将Range设为选中状态
document.getSelection().addRange(range);
</script>
获取用户选中的文本
用户选中文本时,获取用户选中的文本,在实际编码过程中也是经常用到的, 以下代码,当用户选择文字时,会在控制台打印相应的起始和结束边界点。
<body>
<h1>Title</h1>
<p>Blah xyz.</p>
</body>
<script>
//获取用户选中内容的起始和结束边界点
document.onselectionchange = function() {
let {
anchorNode,
anchorOffset,
focusNode,
focusOffset
} = document.getSelection();
//打印,只是做个演示
console.log(anchorNode, anchorOffset)
console.log(focusNode, focusOffset)
};
</script>
Range常用API
下面列出Range常用的API
创建Range
DocumenrRange包含createRange()函数,可用于创建Range对象。
interface DocumentRange {
Range createRange();
}
修改Range的范围
通过修改边界点来修改Range的范围。
void setStart(in Node parent, in long offset)
raises(RangeException);
void setEnd(in Node parent, in long offset)
raises(RangeException);
对比边界点
我们可以通过对比边界点来比较两个Range。
short compareBoundaryPoints(in CompareHow how, in Range sourceRange)
raises(RangeException);
删除Range
void deleteContents();
(1) <FOO>A**B<MOO>CD</MOO>**CD</FOO> --><FOO>A^CD</FOO>
(2) <FOO>A<MOO>B**C</MOO>D**E</FOO> --><FOO>A<MOO>B</MOO>^E</FOO>
(3) <FOO>X**Y<BAR>Z**W</BAR>Q</FOO> --><FOO>X^<BAR>W</BAR>Q</FOO>
(4) <FOO><BAR1>A**B</BAR1><BAR2/><BAR3>C**D</BAR3></FOO>--><FOO><BAR1>A</BAR1>^<BAR3>D</BAR3>
以上是不同情况下,删除Range后,剩下的内容。(其中**内部包含的是否选中的内容)
内容克隆
可以使用如下方法克隆Range中的内容。(注意返回类型)
DocumentFragment cloneContents();
插入内容
可以使用如下方法在Range中插入一个节点。节点将被插入Range的起始边界点处。
void insertNode(in Node n) raises(RangeException);
包裹内容
可以使用如下方法包裹内容。(包裹:使用指定的节点包围Range)
void surroundContents(in Node newParent);
example:
<BAR>A**B<MOO>C</MOO>D**E</BAR>
使用函数 surroundContents(FOO)后:
<BAR>A**<FOO>B<MOO>C</MOO>D</FOO>**E</BAR>
FOO为元素节点。
Range其他接口
// Introduced in DOM Level 2:
interface Range {
readonly attribute Node startContainer;
// raises(DOMException) on retrieval
readonly attribute long startOffset;
// raises(DOMException) on retrieval
readonly attribute Node endContainer;
// raises(DOMException) on retrieval
readonly attribute long endOffset;
// raises(DOMException) on retrieval
readonly attribute boolean collapsed;
// raises(DOMException) on retrieval
readonly attribute Node commonAncestorContainer;
// raises(DOMException) on retrieval
void setStart( in Node refNode, in long offset)
raises(RangeException,
DOMException);
void setEnd( in Node refNode, in long offset)
raises(RangeException,
DOMException);
void setStartBefore( in Node refNode)
raises(RangeException,
DOMException);
void setStartAfter( in Node refNode)
raises(RangeException,
DOMException);
void setEndBefore( in Node refNode)
raises(RangeException,
DOMException);
void setEndAfter( in Node refNode)
raises(RangeException,
DOMException);
void collapse( in boolean toStart)
raises(DOMException);
void selectNode( in Node refNode)
raises(RangeException,
DOMException);
void selectNodeContents( in Node refNode)
raises(RangeException,
DOMException);
// CompareHow
const unsigned short START_TO_START = 0;
const unsigned short START_TO_END = 1;
const unsigned short END_TO_END = 2;
const unsigned short END_TO_START = 3;
short compareBoundaryPoints( in unsigned short how, in Range sourceRange)
raises(DOMException);
void deleteContents()
raises(DOMException);
DocumentFragment extractContents()
raises(DOMException);
DocumentFragment cloneContents()
raises(DOMException);
void insertNode( in Node newNode)
raises(DOMException,
RangeException);
void surroundContents( in Node newParent)
raises(DOMException,
RangeException);
Range cloneRange()
raises(DOMException);
DOMString toString()
raises(DOMException);
void detach()
raises(DOMException);
};
接口中各个属性和函数的意义请参考官方网站。
总结
Range在进行前端Web开发时很少用到,但是在实际开发时,往往会遇到一些问题很难在百度上找到资料,这时不妨到官方网站看看,相信一定会有所收获!