resultmap type属性值_[笔记]Javascript的Selection对象:基本属性

本文作者分享了如何通过实践学习Selection对象,包括其代表的用户选区概念、锚点与焦点的定义,以及关键属性如anchorNode、anchorOffset、focusNode和focusOffset的解析。重点介绍了文本节点的分割原理,并探讨了Selection对象与Range的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

7e817cc05af2a35cb7779ab7f875116f.png

这是我首次在知乎写文章。我决定要这么做,因为:

  1. Web 编辑器开发所需知识点犹如串联,体系庞大内容复杂
  2. 现有的文章让我犯困,没有学习乐趣

所以我试图通过一边阅读文章和文档进行学习,一边写关于学习对象的文章。我期望通过这样的方式,让我能够稳定掌握 Selection 对象的基本知识。

该类型文章的服务对象通常只有我自己,之所以发在知乎也是为了有效保存文章。不过如果你认为文章难以阅读,可以向我提出建议,我会尽量尝试改善。


什么是 Selection 对象

一个 Selection 代表了用户在网页中选择内容的集合。

详细地说,用户按住鼠标,随后拖动鼠标,再松开鼠标——从这个过程中创建的选区就是 Selection 集合中的一个(大概是这样吧,Selection 和 Range 应该是包含关系,Range 代表一个选区, Selection 代表所有选区)。

在了解 Selection 对象的基本属性前,我需要先学习几个术语:

  • anchor 锚点:一个选区的起始,也代表鼠标按下瞬间,光标所在的位置。
  • focus 焦点:一个选区的末尾,也就是鼠标松开瞬间,光标所在的位置。
  • range 范围:选区连续的部分,指的是选区的起始到末尾的地方。

由上面三个术语,我基本明白一个选区是如何诞生的:选区有一个起始的位置,还有一个结束的位置;它开始的地方叫 anchor ,它结束的地方叫 focus ,它从开始到结束的部分叫做 range 。

从 anchor 和 focus 的位置能够反推用户选择文字的方向:

  • 我从右往左选择一段文字,那么 anchor(起始点)在focus(结束点)的右边
  • 我从左往右选择一段文字,那么 anchor(起始点)在focus(结束点)的左边
  • 我点击段落中某一个位置,而不是选择一段文字,那么 anchor(起始点)和 focus(结束点)的位置重叠

创建一个 Selection 对象

现在有一个段落A

<p>A placeholder can be really <b>cool</b> but should it? I doubt that.<br/></p>

我在段落A中,从左往右选择了一段文字:

can be

之后,我通过 window.getSelection() 方法,获取到以下内容:

{
  anchorNode: text
  anchorOffset: 14
  baseNode: text
  baseOffset: 14
  extentNode: text
  extentOffset: 20
  focusNode: text
  focusOffset: 20
  isCollapsed: false
  rangeCount: 1
  type: "Range"
  __proto__: Selection
}

这是一个 type 值为 "range" 的的 Selection 对象,包含了我刚选择的选区信息——我把它命名为 selectionA

待会儿我会将selectionA的主要属性进行一番解析。

文本节点的分割

在了解 Selection 的属性之前,我们还需要学习文本节点的分割原理,因为文本节点是我们理解 Selection 属性的基础。

这是上面定义的段落A

<p>A placeholder can be really <b>cool</b> but should it? I doubt that.<br/></p>

根据标签进行分割后,会得出这些节点:

节点1 "A placeholder can be really " 
节点2 "cool"
节点3 "but should it? I doubt that."

它们就是文本节点,稍微理解一下就能明白其中的逻辑。

需要注意的是,虽然文本节点是 Text 对象的主要内容,但不是唯一内容。比如,下面是一个代表节点1的 Text 对象:

{
  assignedSlot: null
  baseURI: "http://localhost:8080/"
  childNodes: NodeList []
  data: "A placeholder can be really "
  firstChild: null
  isConnected: true
  lastChild: null
  length: 28
  nextElementSibling: b
  nextSibling: b
  nodeName: "#text"
  nodeType: 3
  nodeValue: "A placeholder can be really "
  ownerDocument: document
  parentElement: p
  parentNode: p
  previousElementSibling: null
  previousSibling: null
  textContent: "A placeholder can be really "
  wholeText: "A placeholder can be really "
}

可以看出,Text 对象内其实包含许多有的没的属性。所以,我们在具体操作 Text 对象时,还需要了解它的各种属性。当然这个之后再说,当务之急是了解整个 Selection 对象的大体情况。


Selection 对象的基本属性

anchorNode

anchorNode 是一个 Text 对象,它代表 anchor(起始点)所在的文本节点对象。

我知道段落A经过分割后,得出下列节点:

节点1 "A placeholder can be really " 
节点2 "cool"
节点3 "but should it? I doubt that."

在 selectionA 中,我选择了这段内容:

can be

这串字符所在的文本节点为节点1。我可以暂时这么理解:

selectionA.anchorNode = 节点1

当然,selectionA.anchorNode 是一个 Text 对象而不只是简单的 String 对象。为什么我说可以暂时将 selectionA.anchorNode 与节点1划上等号呢?

selectionA.anchorNode 有个重要的属性:

{
  ...
  textContent: "A placeholder can be really "
  ...
}

这个属性是 selectionA.anchorNode的主要属性,而可以看出,selectionA.anchorNode.textContent 的内容等于节点1的内容。所以我暂时这样理解是没有错的,这有助于我理解整个 Selection 对象的内容。

selectionA.anchorNode 包含了不少属性,但我们现在需要从整体理解 Selection 对象,还没到详细剖析的时候。所以现在,我们只需要知道 selectionA.anchorNode ,也就是起始文本节点,代表了什么,以及文本节点们是如何被划分的,这就足够了。

anchorOffset

anchorOffset 是一个数值,它代表了 anchor(起始点)在对应文本节点的偏移量。

我知道 selectionA.anchorNode 的主要内容为:

A placeholder can be really 

而 selectionA.anchorOffset 的值为:

14

所以 anchor(起始点)在 selectionA.anchorNode 内容的从左往右数第 15 位字符的左侧(从0开始数):

A placeholder |can be really 

看,它在竖线所指的地方。

focusNode

focusNode 是一个 Text 对象,它代表 focus(结束点)所在的文本节点对象。

我知道段落A经过分割后,得出下列节点:

节点1 "A placeholder can be really " 
节点2 "cool"
节点3 "but should it? I doubt that."

在 selectionA 中,我选择了这段内容:

can be

由于所选内容没有跨越标签, selectionA.focusNode 的内容和 selectionA.anchorNode 的内容一样,等于节点1。

这个属性由于上面进行了类似的解析,所以没有太多可以说的内容。

focusOffset

focusOffset 是一个数值,它代表了 focus(结束点)在对应文本节点的偏移量。

该属性的意义和 selectionA.anchorOffset 是类似的,只不过 selectionA.focusOffset 属性代表的是 focus(结束点)的文本节点偏移量。

已知节点A内容为:

A placeholder can be really 

而 selectionA.focusOffset 的值为:

20

则该位置在竖线位置,也就是从0开始,从左往右第20位字符的左侧:

A placeholder can be| really 

isCollapsed

isCollapsed 是一个 Boolean 值,它表示 anchor(起始点)和 focus(结束点)是否处在同一位置。

当我只是点击段落的某个位置,而不是选择一个区间,那么我获取到的 Selection 对象,它的anchor(起始点)和focus(结束点)在同一个位置,则这时候, isCollapsed 属性的值为:

true

对于selectionA,它的 range 是有长度的,则 selectionA.isCollapsed的值为

false

rangeCount

rangeCount 是一个数值,它表示 Selection 对象获取到多少个 range 。

通常情况下, rangeCount 为0或者1,因为浏览器一般不允许用户选择多个 range 。当用户没有选择任何区域,则 rangeCount 值为:

0

对于selectionA,它的 range 只有一个,则 selectionA.rangeCount 的值为:

1

type

type 是一个字符串,它表示 Selection 对象的类型。

当用户选取了一个范围,则 type 的值为

Range

当用户点击了某处而非选取了一个范围,则 type 的值为

Caret

对于selectionA,它是一个范围,则 type 的值为

Range

总结

学到这里,我基本了解了 Selection 对象的基本属性,但在运用方面、概念方面,我还不是很明白。

Selection 对象和 Range 对象在我看来是属性很相似的两种对象,甚至 Range 对象的基础属性都比 Selection 对象要少许多,但仍能诠释两者的特点。比如说,它们都有开始节点、结束节点。

而对于 Selection里面不少内容相同的属性,它们究竟是用来做什么的,我还没有搞明白,比如 baseNode、 extentNode。

说 Selection 是 Range 的集合,但多个 Range 的情况很多见吗?我甚至无法通过 ctrl + 鼠标选中多个 Range……

只是跟着MDN和一些文章来进行学习,看来的确是不够的。下一步还需要了解相关的方法,还需要多实践才能明白它的作用吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值