Range
和 Selection
API 是浏览器提供的用于处理用户文本选区和光标位置的强大工具。以下是如何使用这些 API 精确管理光标位置和选区的详细介绍,包括示例代码。
1. 基本概念
- Range: 表示文档中的连续区域,可以包含部分节点和文本节点。
- Selection: 表示用户当前选择的文本范围,通常包含一个或多个
Range
对象。
2. 获取和操作选区
获取当前选区
要获取用户当前的选区,可以使用 window.getSelection()
方法:
const selection = window.getSelection();
创建一个 Range
使用 document.createRange()
创建一个新的 Range
对象:
const range = document.createRange();
3. 设置光标位置
将光标移动到特定位置
假设我们有一个可编辑的 div
元素,并希望将光标移动到这个元素的末尾:
<div id="editable" contenteditable="true">Hello, World!</div>
以下是实现方法:
const editableDiv = document.getElementById('editable');
const range = document.createRange();
const selection = window.getSelection();
// 将光标移动到内容的末尾
range.selectNodeContents(editableDiv);
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
将光标移动到特定文本节点的特定偏移位置
假设我们希望将光标移动到 div
内部的某个文本节点的特定位置:
const textNode = editableDiv.childNodes[0]; // 假设这是文本节点 "Hello, World!"
const offset = 5; // 将光标移动到 "Hello" 之后
range.setStart(textNode, offset);
range.collapse(true);
selection.removeAllRanges();
selection.addRange(range);
4. 获取和设置选区内容
获取选区的文本内容
如果需要获取用户当前选中的文本,可以直接从 Selection
对象中获取:
const selectedText = selection.toString();
console.log(selectedText);
设置选区内容
我们也可以使用 Range
对象来替换选区中的内容:
const newText = document.createTextNode('New Content');
range.deleteContents();
range.insertNode(newText);
// 更新选区范围
selection.removeAllRanges();
range.selectNode(newText);
selection.addRange(range);
5. 高亮选区
可以通过设置 Range
对象的边界来高亮特定区域:
const startNode = editableDiv.childNodes[0];
const endNode = editableDiv.childNodes[0];
// 高亮 "Hello"
range.setStart(startNode, 0);
range.setEnd(endNode, 5);
selection.removeAllRanges();
selection.addRange(range);
6. 处理复杂的嵌套结构
在处理复杂的嵌套结构时,光标管理会变得更加复杂。以下是一个示例,展示如何在嵌套元素中管理光标:
<div id="editable" contenteditable="true">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</div>
将光标移动到第二个段落的开头:
const secondParagraph = editableDiv.childNodes[1];
const textNode = secondParagraph.childNodes[0];
// 将光标移动到第二个段落的开头
range.setStart(textNode, 0);
range.collapse(true);
selection.removeAllRanges();
selection.addRange(range);
7. 示例总结
完整的代码示例展示了如何创建一个简单的 contenteditable
编辑器,并管理光标位置和选区:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ContentEditable Example</title>
<style>
#editable {
border: 1px solid #ccc;
padding: 10px;
min-height: 100px;
}
</style>
</head>
<body>
<div id="editable" contenteditable="true">Hello, World!</div>
<button onclick="moveCursorToEnd()">Move Cursor to End</button>
<button onclick="replaceSelection()">Replace Selection</button>
<script>
function moveCursorToEnd() {
const editableDiv = document.getElementById('editable');
const range = document.createRange();
const selection = window.getSelection();
// 将光标移动到内容的末尾
range.selectNodeContents(editableDiv);
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
}
function replaceSelection() {
const editableDiv = document.getElementById('editable');
const selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
range.deleteContents();
const newText = document.createTextNode('New Content');
range.insertNode(newText);
// 更新选区范围
range.selectNode(newText);
selection.removeAllRanges();
selection.addRange(range);
}
}
</script>
</body>
</html>