diff --git a/2-ui/99-ui-misc/02-selection-range/article.md b/2-ui/99-ui-misc/02-selection-range/article.md index 35f2f7fb50..a1caa72e78 100644 --- a/2-ui/99-ui-misc/02-selection-range/article.md +++ b/2-ui/99-ui-misc/02-selection-range/article.md @@ -4,29 +4,29 @@ libs: --- -# 选区(Selection)和范围(Range) +# 选择(Selection)和范围(Range) -在本章中,我们将介绍文档中的选区以及表单字段(如 ``)中的选区。 +在本章中,我们将介绍文档中的选择以及在表单字段(如 ``)中的选择。 -JavaScript 可以获取现有选区,全部或部分选择/取消选择,从文档中删除所选择的部分,将其包到一个标记(tag)中,等等。 +JavaScript 可以获取现有选择,选择/取消全部或部分选择,从文档中删除所选部分,将其包装到一个标签(tag)中,等。 -最后,您可以在文末的"总结"部分中找到使用方法。但是,如果您阅读整章内容,将会获得更多。基本的 `Range` 和 `Selection` 对象很容易掌握,因此不需要任何诀窍便可实现你想要的操作。 +你可以在本文最后的“总结”部分中找到使用方法。但是,如果你阅读整篇内容,将会有更多收获。底层的(underlying)`Range` 和 `Selection` 对象很容易掌握,因此,你不需要任何诀窍便可以使用它们做你想要做的事儿。 ## 范围 -选区的基本概念是 [Range](https://dom.spec.whatwg.org/#ranges):本质上是一对“边界点”:范围起点和范围终点。 +选择的基本概念是 [Range](https://dom.spec.whatwg.org/#ranges):本质上是一对“边界点”:范围起点和范围终点。 -每个点都表示为一个父 DOM 节点,从起点偏移一段距离。如果父节点是元素节点,则偏移量是子节点个数,对于文本节点而言,则是文本中的位置。下面举例来说。 +每个点都被表示为一个带有相对于起点的相对偏移(offset)的父 DOM 节点。如果父节点是元素节点,则偏移量是子节点的编号,对于文本节点,则是文本中的位置。下面举例说明。 -让我们选择点什么。 +让我们选择一些东西。 -首先,我们可以创建一个范围(构造函数不带参数): +首先,我们可以创建一个范围(构造器没有参数): ```js let range = new Range(); ``` -然后,我们可以使用 `range.setStart(node, offset)` 和 `range.setEnd(node, offset)` 来设置选区边界。 +然后,我们可以使用 `range.setStart(node, offset)` 和 `range.setEnd(node, offset)` 来设置选择边界。 例如,考虑以下 HTML 片段: @@ -34,7 +34,7 @@ let range = new Range();

Example: italic and bold

``` -这是它的 DOM 结构,请注意,这里的文本节点对我们很重要: +这是其 DOM 结构,请注意,这里的文本节点对我们很重要:
@@ -72,7 +72,7 @@ let selectPDomtree = { drawHtmlTree(selectPDomtree, 'div.select-p-domtree', 690, 320); -我们来选择 `"Example: italic"`。那是 `

` 的头两个子节点(文本节点包括在内): +让我们来选择 `"Example: italic"`。它是 `

` 的前两个子节点(文本节点也算在内): ![](range-example-p-0-1.svg) @@ -90,15 +90,15 @@ drawHtmlTree(selectPDomtree, 'div.select-p-domtree', 690, 320); // 范围的 toString 以文本形式返回其内容(不带标签) alert(range); // Example: italic - // 将此范围应用于文档选区(稍后解释) + // 将此范围应用于文档选择(后文有解释) document.getSelection().addRange(range); ``` -- `range.setStart(p, 0)` - 将起始位置设为 `

` 的第 0 个子节点(即文本节点 `"Example: "`)。 -- `range.setEnd(p, 2)` - 覆盖范围至(但不包括)`

` 的第 2 个子节点(即文本节点 `" and "`,但由于不包括末节点,最后选择的节点是 ``)。 +- `range.setStart(p, 0)` —— 将起点设置为 `

` 的第 0 个子节点(即文本节点 `"Example: "`)。 +- `range.setEnd(p, 2)` —— 覆盖范围至(但不包括)`

` 的第 2 个子节点(即文本节点 `" and "`,但由于不包括末节点,所以最后选择的节点是 ``)。 -下面的测试更加灵活,您可以在其中尝试更多不同的情况: +这是一个更灵活的测试台,你可以在其中尝试更多不同的情况: ```html run autorun

Example: italic and bold

@@ -114,7 +114,7 @@ From – To – To ample: " 中除头两个字符外的所有字符) -- 到 `` 的第一个子节点的位置 3 结束(选择 "bold" 的头三个字符,就这些): +我们需要创建一个范围,它: +- 从 `

` 的第一个子节点的位置 2 开始(选择 "Example: " 中除前两个字母外的所有字母) +- 到 `` 的第一个子节点的位置 3 结束(选择 "bold" 的前三个字母,就这些): ```html run

Example: italic and bold

@@ -150,62 +150,62 @@ From – To Example: italic and bold

@@ -213,7 +213,7 @@ From – To – To Select me: italic and bold

@@ -334,13 +334,13 @@ From – To ``` -### 选区获取示例代码 +### 选择获取演示 -如要获取整个选区: +要获取整个选择: - 作为文本:只需调用 `document.getSelection().toString()`。 -- 作为 DOM 节点:获取底层的范围并调用其 `cloneContents()` 方法(如果我们不支持 Firefox 多选区的话,则仅取第一个范围)。 +- 作为 DOM 节点:获取底层的(underlying)范围,并调用它们的 `cloneContents()` 方法(如果我们不支持 Firefox 多选的话,则仅取第一个范围)。 -下面是将选区选作为文本和 DOM 节点的示例代码: +下面是将选择内容获取为文本和 DOM 节点的演示: ```html run height=100

Select me: italic and bold

@@ -360,35 +360,35 @@ As text: cloned.append(selection.getRangeAt(i).cloneContents()); } - // 以文本形式获取 + // 获取为文本形式 astext.innerHTML += selection; }; ``` -## 选区方法 +## 选择方法 -添加/删除范围的选区方法: +添加/移除范围的选择方法: -- `getRangeAt(i)` - 获取从 `0` 开始的第 i 个范围。在除 Firefox 之外的所有浏览器中,仅使用 `0`。 -- `addRange(range)` - 将 `range` 添加到选区中。如果选区已有关联的范围,则除 Firefox 外的所有浏览器都将忽略该调用。 -- `removeRange(range)` - 从选区中删除 `range`。 -- `removeAllRanges()` - 删除所有范围。 -- `empty()` - `removeAllRanges` 的别名。 +- `getRangeAt(i)` —— 获取从 `0` 开始的第 i 个范围。在除 Firefox 之外的所有浏览器中,仅使用 `0`。 +- `addRange(range)` —— 将 `range` 添加到选择中。如果选择已有关联的范围,则除 Firefox 外的所有浏览器都将忽略该调用。 +- `removeRange(range)` —— 从选择中删除 `range`。 +- `removeAllRanges()` —— 删除所有范围。 +- `empty()` —— `removeAllRanges` 的别名。 -另外,还有一些方便的方法可以直接操作选区范围,而无需使用 `Range`: +另外,还有一些方便的方法可以直接操作选择范围,而无需使用 `Range`: -- `collapse(node, offset)` - 用一个新的范围替换选定的范围,该新范围从给定的 `node` 处开始,到偏移 `offset` 处结束。 -- `setPosition(node, offset)` - `collapse` 的别名。 -- `collapseToStart()` - 折叠(以空范围替换)到选区起点, -- `collapseToEnd()` - 折叠到选区终点, -- `extend(node, offset)` - 将选区的焦点移到给定的 `node`,位置偏移 `oofset`, -- `setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset)` - 用给定的起点 `anchorNode/anchorOffset` 和 终点 `focusNode/focusOffset` 来替换选区范围。选中它们之间的所有内容。 -- `selectAllChildren(node)` - 选择 `node` 的所有子节点。 -- `deleteFromDocument()` - 从文档中删除所选内容。 -- `containsNode(node, allowPartialContainment = false)` - 检查选区中是否包含 `node`(特别是如果第二个参数是 `true` 的话) +- `collapse(node, offset)` —— 用一个新的范围替换选定的范围,该新范围从给定的 `node` 处开始,到偏移 `offset` 处结束。 +- `setPosition(node, offset)` —— `collapse` 的别名。 +- `collapseToStart()` —— 折叠(替换为空范围)到选择起点, +- `collapseToEnd()` —— 折叠到选择终点, +- `extend(node, offset)` —— 将选择的焦点(focus)移到给定的 `node`,位置偏移 `oofset`, +- `setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset)` —— 用给定的起点 `anchorNode/anchorOffset` 和终点 `focusNode/focusOffset` 来替换选择范围。选中它们之间的所有内容。 +- `selectAllChildren(node)` —— 选择 `node` 的所有子节点。 +- `deleteFromDocument()` —— 从文档中删除所选择的内容。 +- `containsNode(node, allowPartialContainment = false)` —— 检查选择中是否包含 `node`(特别是如果第二个参数是 `true` 的话) -因此,对于许多任务,我们可以调用 `Selection` 方法,而无需访问底层的 `Range` 对象。 +因此,对于许多任务,我们可以调用 `Selection` 方法,而无需访问底层的(underlying)`Range` 对象。 例如,选择段落 `

` 的全部内容: @@ -396,63 +396,63 @@ As text:

Select me: italic and bold

``` -同样用范围来做: +使用范围来完成同一个操作: ```html run

Select me: italic and bold

``` -```smart header="如要选择,先删除现有的选区" -如果选区已存在,则先用 `removeAllRanges()` 删除之。然后添加范围。否则,除 Firefox 外的所有浏览器都将忽略新范围。 +```smart header="如要选择,请先移除现有的选择" +如果选择已存在,则首先使用 `removeAllRanges()` 将其清空。然后添加范围。否则,除 Firefox 外的所有浏览器都将忽略新范围。 -某些选区方法是一个例外,它们会替换现有的选区,例如 `setBaseAndExtent`。 +某些选择方法例外,它们会替换现有的选择,例如 `setBaseAndExtent`。 ``` -## 表单控件中的选区 +## 表单控件中的选择 -表单元素如 `input` 和 `textarea` 提供 [选区专用 API](https://html.spec.whatwg.org/#textFieldSelection),没有 `Selection` 或 `Range` 对象。由于输入值是纯文本而不是 HTML,因此不需要此类对象,一切都变得更加简单。 +诸如 `input` 和 `textarea` 等表单元素提供了 [专用的选择 API](https://html.spec.whatwg.org/#textFieldSelection),没有 `Selection` 或 `Range` 对象。由于输入值是纯文本而不是 HTML,因此不需要此类对象,一切都变得更加简单。 属性: -- `input.selectionStart` - 选区的起始位置(可写), -- `input.selectionEnd` - 选区的结束位置(可写), -- `input.selectionDirection` - 选区方向,可以是:"forward", "backward" 或 "none"(如通过双击选区), +- `input.selectionStart` —— 选择的起始位置(可写), +- `input.selectionEnd` —— 选择的结束位置(可写), +- `input.selectionDirection` —— 选择方向,其中之一:"forward","backward" 或 "none"(例如使用鼠标双击进行的选择), 事件: -- `input.onselect` - 选择某项时触发。 +- `input.onselect` —— 当某个东西被选择时触发。 方法: -- `input.select()` - 选择文本控件中的所有内容(可以是 `textarea` 而不是 `input`), -- `input.setSelectionRange(start, end, [direction])` - 在给定方向上(可选),从 `start` 一直选择到 `end`。 -- `input.setRangeText(replacement, [start], [end], [selectionMode])` - 用新文本替换文本范围。 +- `input.select()` —— 选择文本控件中的所有内容(可以是 `textarea` 而不是 `input`), +- `input.setSelectionRange(start, end, [direction])` —— 在给定方向上(可选),从 `start` 一直选择到 `end`。 +- `input.setRangeText(replacement, [start], [end], [selectionMode])` —— 用新文本替换范围中的文本。 - 可选参数 `start` 和 `end`,如果提供的话,则设置范围的起点和终点,否则使用用户选区。 + 可选参数 `start` 和 `end`,如果提供的话,则设置范围的起点和终点,否则使用用户的选择。 - 最后一个参数 `selectionMode` 决定替换文本后如何设置选区。可能的值为: + 最后一个参数 `selectionMode` 决定替换文本后如何设置选择。可能的值为: - - `"select"` - 将选择新插入的文本。 - - `"start"` - 选区范围在插入的文本之前折叠(光标将在其之前)。 - - `"end"` - 选区范围在插入的文本之后折叠(光标将在其后)。 - - `"preserve"` - 尝试保留选区。这是默认值。 + - `"select"` —— 将选择新插入的文本。 + - `"start"` —— 选择范围将在插入的文本之前折叠(光标将在其之前)。 + - `"end"` —— 选择范围将在插入的文本之后折叠(光标将紧随其后)。 + - `"preserve"` —— 尝试保留选择。这是默认值。 现在,让我们看看这些方法的实际使用。 -### 示例:跟踪选区 +### 示例:跟踪选择 -例如,此段代码使用 `onselect` 事件来跟踪选区: +例如,此段代码使用 `onselect` 事件来跟踪选择: ```html run autorun