# Selection
# Selection 对象
首先,它是一个对象。
获取对象的方法是:
window.getSelection();
它表示用户拖拽鼠标经过文字选择文本的范围或者插入符号的当前位置(比如鼠标在某个文字上点击),在它表示文本选区时,可能会横跨多个元素。
通常,插入光标的位置是可以通过 Selection
获取的,此时的 Selection
对象的 Collpase
属性是 true
,表示选区被压缩至一点了,即光标的位置。
如下图,我在 “的” 字后面进行鼠标点击,实时获取的 Selection
对象信息,它能标记处我鼠标点击的位置和Collpase
属性值。
如果我们是划选一个文本段,获取的 Selection
对象信息中部分字段就不一样了。
# Selection 对象属性
# anchorNode
只读属性。
表示该选区起点所在的节点(Node 节点),它包含的内容如下:
# anchorOffset
只读属性
它是一个数字,表示选区起点在 anchorNode
中的位置偏移量。
如果
anchorNode
是文本节点,那么返回的就是从该文字节点的第一个字开始,直到被选中的第一个字之间的字数。举个 🌰:
上图中,“多地正向社会公布流感监测的最新情况。” 这句话,我从 “多” 字就选中了。也就是第一个字就被选中,那么偏移量为零。
如果上图我从 “正向..” 开始选中,那么偏移量就是 2。
这个开始的计数是从每个文字的前面开始计算的,第一个文字的前面的
offset
就是0
。如果
anchorNode
是一个元素,那么返回的就是在选区第一个节点之前的同级节点总数。(这些节点都是anchorNode
的子节点)。这个没有找到验证例子。
# focusNode
只读属性
与 anchorNode 同理,它表示的是选区终点所在的节点。
# focusOffset
只读属性
它是一个数字,表示选区起点在 focusNode
中的位置偏移量。
- 如果
focusNode
是文本节点,那么选区末尾被选中的第一个字,在该文字节点中是第几个字(从 0 开始计算),就返回它。
那 anchorNode
中的 🌰 来说:如果 “多地正向社会公布流感监测的最新情况。” 这句话,我从头划选到了倒数第三个字 “新”,那 focusOffset
就是 15。
结束位置的计数是从选中文字与未选中文字中间的位置偏移量作为结果的,从第一个字前面以 0 开始的。
- 如果 focusNode 是一个元素,那么返回的就是在选区末尾之后第一个节点之前的同级节点总数。
# isCollapsed
只读属性
返回一个布尔值,用于判断选区的起始点和终点是否在同一个位置。
# rangeCount
只读属性
返回该选区所包含的连续范围的数量。
注意它和获取 Range
对象时有所关联:
假如 rangeCount 是 1, 它表示当前选区所包含的连续范围的数量是 1。关联到 Range
范围时,就可以理解成一个数组内只有一个值,长度是 1。
所以从当前 Selection
对象中获取 Range
对象时, 就是 Selection.getRangeAt(0)
。
如果此时 getRangeAt(index)
中的 index 值大于或者等于 1,那就会抛出错误。
# anchor 与 focus
这两张图中有两个关键字:anchor 和 focus。
- anchor 是指用户开始选择文本的位置,鼠标键按下的地方。
- focus 是指用户选择文本结束的位置,鼠标键抬起的地方。
anchor 和 focus 不能代表选区的起始位置和结束位置。因为每个人选择文本的方式不同,有喜欢 从左到右(从上倒下) 的,有喜欢倒着选择 从优到左(从下到上) 选择文本的。
所以,anchor 和 focus 谁在前,谁在后是不确定的。
# 选区范围的内容
如果想要获取划选范围内的的内容,可以通过 toString()
方法获取。
Selection.toString();
该方法会返回被选中区域的纯文本,要求变量为字符串的函数会自动对对象进行该处理。
# Range 对象
Selection
对象所对应的是用户选择的一个区域,即 ranges
,又称拖蓝。
默认情况下,这只是一个区域,但是在 firfox 浏览器上,通过 control 键可以产生多个拖蓝,这是需要注意的点。
Range 对象也能通过 DOM 创建、增加、删减。
获取 range 对象方式如下:
// 获取 selection 对象
var selectionObj = window.getSelection();
// 从 selection 对象中获取 range 对象
var range = selectionObj.getRangeAt(0);
来看一下,在上面两个 Selection
对象下,产生的 Range
对象有什么区别: