对一段文字进行编辑基础操作之一就是框选。比如想在页面上复制一段文字,我们可以用鼠标选中,然后ctrl+c
。其实浏览器也给我们提供丰富的框选操作API,如果你想基于contenteditable
属性实现富文本编辑器
,这些API是必不可少的存在。
Range对象
想要操作用户选择区域要做两件事:
- 告诉浏览器一段
范围
- 对范围进行
选择操作
Range
对象就是对一个连续内容范围
的描述
。
可以通过以下3种方式获得Range对象:
// 方式1,隶属于Document对象的Range()构造函数
let range1 = new Range()
// 方式2,document.createRange()
let range2 = document.createRange()
// 方式3,Selection.getRangeAt()
let selection = window.getSelection()
let range3 = selection.getRangeAt(0)
// 参数「index」表示选择区域的索引,一般是0,Firefox中可以选中多个区域
// 此种方式内涵了起始位置信息
有了Range
还没用,作为一个描述区域的对象,一个空的Range
对象没有任何意义,我们必须指定它的起始和终止位置。Range对象给我们提供了两个方法:
setStart(node, offset)
setEnd(node, offset)
直接上代码:
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
<script>
let range = new Range()
range.setStart(p, 0)
range.setEnd(p, 2)
// 范围的 toString 以文本形式返回其内容(不带标签)
alert(range) // Example: italic
console.log(range) // Range{...}
// 将此范围应用于文档选择(后文有解释)
document.getSelection().addRange(range)
</script>
setStart和setEnd都有两个参数,参数一node
是目标Node
节点,它一般可以是Element
或者Text
对象。如果是Element
对象(比如上例),第二个offset
参数表示标签元素的(从0
开始)第几个子元素(的前方定位
):
如果node
是Text
,offset
则表示文本的(从0
开始)第几个字符(的前方定位
):
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
<script>
let range = new Range();
range.setStart(p.firstChild, 2);
range.setEnd(p.querySelector('b').firstChild, 3);
alert(range); // ample: italic and bol
// 使用此范围进行选择(后文有解释)
window.getSelection().addRange(range);
</script>
Range属性
- 上图中
startContainer
,startOffset
起始节点的偏移量 = 2 - 上图中
endContainer
,endOffset
结束节点的偏移量 = 3 collapsed
布尔值,表示范围是否在同一点上开始和结束(无选中内容)commonAncestorContainer
范围内所有节点的最近共同祖先节点,本例中为#p
Range方法
- 起点
- setStart(node, offset)
- setStartBefore(node) 将起点设在
node
前面 - setStartAfter(node) 将起点设在
node
后面
- 终点
- setEnd(node, offset)
- setEndBefore(node) 将终点设在
node
前面 - setEndAfter(node) 将终点设在
node
后面
- 整个node
- selectNode(node) 选择节点
及
内容 - selectNodeContents(node) 选择节点
的
内容 - collages(toStart) 为
true
时end=start
(收缩到头部),否则start=end
(收缩到末尾) - cloneRange() 拷贝范围
- selectNode(node) 选择节点
- 操作内容
- deleteContents() 删除范围内容
- extractContents() 删除范围内容,并返回包裹
DocuemntFragment
(DOM节点容器)的被删内容 - cloneContents() 复制范围内容,返回包裹
DocuemntFragment
的选中内容 - insertNode(node) 在范围的起始处将
node
插入文档 - surroundContents(node) 使用
node
将范围内容包裹起来。该范围必须包含范围内所有元素的开始和结束标签,不能想<i>abc
这样
以上。 原创不易,欲转先告知,欢迎加我交流: