- 选区: 鼠标选中的那一部分,通常是蓝色
- 光标:闪烁的竖线
- “选区”和“光标”是什么?
-
Selection 对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区,可能横跨多个元素。通常由用户拖拽鼠标经过文字而产生。
-
获取
selection
,可以通过全局的 getSelection方法:
const selection = window.getSelection();
-
通常情况下我们不会直接操作
selection
对象,而是需要操作用seleciton
对象所对应的用户选择的range
const range = selection.getRangeAt(0);
注意:firefox支持多选区,可以通过selection
返回的rangeCount
看;因此getRangeAt需要传入一个序号,但目前就只有火狐支持多选区,其他在那不考虑 -
获取选区的内容:这个暂时只支持不可编辑元素,可编辑的会获取不到
window.getSelection().toString() // 或者 window.getSelection().getRangeAt(0).toString()
-
-
Range 对象表示包含节点和部分文本节点的文档片段。通过
selection
对象获得的range
对象才是我们操作光标的重点。- collapsed:表示选区的起点与终点是否重叠。true表示重叠
- 光标:选区的起点与终点重叠
-
- input和textarea选区操作
-
主动选中某一区域:
setSelectionRange(selectionStart, selectionEnd [, selectionDirection])
- selectionStart :开始位置
- selectionEnd:结束位置
- selectionDirection:方向
txt.setSelectionRange(0,2); txt.focus();
-
聚焦到某一位置(起始位置一样):
txt.setSelectionRange(2, 2)
-
还原之前的选区:有时候,我们需要在点击其他地方后,再重新选中之前的选区。
const pos = {} document.onmouseup = (ev) => { pos.start = txt.selectionStart; pos.end = txt.selectionEnd; } btn.onclick = () => { txt.setSelectionRange(pos.start,pos.end) txt.focus(); }
-
在指定选区插入(替换)内容:
setRangeText(replacement)
;setRangeText(replacement, start, end [, selectMode])
- replacement:表示需要替换的文本
- start:开始位置
- end:结束位置
- selectMode:替换后选区的状态(select 替换后选中;start 替换后光标位于替换词之前;end 替换后光标位于替换词之后; preserve 默认值,尝试保留选区)
- 尝试保留选区:假设手动选中的区域是
[9,10]
,如果在[1,2]
的位置替换新内容,那么选区仍然在之前位置。如果在[8,11]
的位置替换新内容,由于新内容的位置覆盖了之前的选区,原选区也就不存在了,那么替换完之后,选区会选中刚刚插入的新内容
- 尝试保留选区:假设手动选中的区域是
-
- 普通元素的选取操作
-
主动选中某一区域(这要求偏移量不能超过一个节点的最大偏移量,不适用于包含富文本)
- 先设置区域的起始位置:range.setStart(startNode, startOffset);range.setEnd(endtNode, endOffset);
- 注意:如果起始节点类型是
Text
,Comment
, orCDATASection
之一, 那么startOffset
指的是从起始节点算起字符的偏移量。 对于其他Node
类型节点,startOffset
是指从起始结点开始算起子节点的偏移量。
- 注意:如果起始节点类型是
- 移除选区:selection.removeAllRanges()
- 添加选区:selection.addRange(range)
- 先设置区域的起始位置:range.setStart(startNode, startOffset);range.setEnd(endtNode, endOffset);
-
主动选中富文本中的某一区域(富文本:支持内嵌标签)
- 找选中区间的节点和偏移量
-
递归遍历,找到所有文本节点 #text
-
计算文本的位置区间
-
查找满足条件的范围区间
-
- 找选中区间的节点和偏移量
-
聚焦到某一位置
只需要把起始位置设置相同
-
还原之前的选区
- 计算相对于整段文本的偏移量
-
遍历,找出所有的#text
-
计算文本的位置区间
-
匹配选区与区间的#text,计算偏移量
-
- 计算相对于整段文本的偏移量
-
在指定选区插入(替换)内容
-
range.insertNode:在选区的起点处插入一个节点,并不会替换掉当前已选中的。
-
deleteContents:删除选区的内容
-
document.createTextNode: 创建文本
-
document.createElement: 创建带标签的文本
-
range.setStartAfter:设置区间的起点为该元素的后面
-
-
给指定选区包裹标签
-
range.surroundContents:表示给选区包裹一层标签
注意:当选区有“断层”时,会报错。比如:
-
先通过
range.extractContents
方法获取选区的内容,然后将选区内容添加到新节点上,最后插入新内容(避免选区有断层现象出现)
-
-