js实现光标
光标操作基础方法
在JavaScript中操作光标通常涉及DOM元素的selection和range对象。通过这两个核心API可以精确控制光标位置、选中文本范围等行为。
获取当前光标位置:
const selection = window.getSelection();
const range = selection.getRangeAt(0);
const cursorPosition = range.startOffset;
设置光标到元素末尾:
const element = document.getElementById('editable');
const range = document.createRange();
range.selectNodeContents(element);
range.collapse(false); // true为开头,false为末尾
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
输入框光标控制
对于<input>或<textarea>元素,可以使用更简单的selection API:
获取光标位置:
const input = document.querySelector('input');
const startPos = input.selectionStart;
const endPos = input.selectionEnd;
设置光标位置:

input.setSelectionRange(3, 5); // 选中第3到第5个字符
input.focus(); // 需要先获取焦点
富文本编辑器光标处理
在contenteditable元素中操作光标更复杂,需要处理跨节点的情况:
插入文本到光标处:
function insertTextAtCursor(text) {
const selection = window.getSelection();
if (selection.rangeCount) {
const range = selection.getRangeAt(0);
range.deleteContents();
const textNode = document.createTextNode(text);
range.insertNode(textNode);
// 移动光标到插入内容之后
range.setStartAfter(textNode);
range.collapse(true);
selection.removeAllRanges();
selection.addRange(range);
}
}
保存与恢复光标位置
需要先保存光标状态:

function saveCursorPosition(editableDiv) {
const selection = window.getSelection();
const range = selection.getRangeAt(0);
const preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(editableDiv);
preSelectionRange.setEnd(range.startContainer, range.startOffset);
const start = preSelectionRange.toString().length;
return { start, end: start + range.toString().length };
}
恢复光标位置:
function restoreCursorPosition(editableDiv, savedPos) {
const charIndex = 0;
const range = document.createRange();
range.setStart(editableDiv, 0);
range.collapse(true);
let nodeStack = [editableDiv], node, foundStart = false;
while (!foundStart && (node = nodeStack.pop())) {
if (node.nodeType === 3) {
const nextCharIndex = charIndex + node.length;
if (!foundStart && savedPos.start >= charIndex && savedPos.start <= nextCharIndex) {
range.setStart(node, savedPos.start - charIndex);
foundStart = true;
}
charIndex = nextCharIndex;
} else {
let i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i]);
}
}
}
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
常见光标操作场景
移动光标到特定元素:
function moveCursorToElement(element) {
const range = document.createRange();
range.selectNodeContents(element);
range.collapse(false);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
获取当前选中文本:
const selectedText = window.getSelection().toString();
删除光标前的字符:
function deleteBeforeCursor() {
const selection = window.getSelection();
if (!selection.rangeCount) return;
const range = selection.getRangeAt(0);
if (range.startOffset === 0) return;
const newRange = range.cloneRange();
newRange.setStart(range.startContainer, range.startOffset - 1);
newRange.deleteContents();
}
这些方法覆盖了JavaScript中光标操作的主要场景,实际应用中可能需要根据具体需求进行调整组合。






