Web API 中不存在 selection.collapse() 方法,正确做法是用 Range.collapse() 配合 removeAllRanges() 和 addRange() 实现光标定位。

Selection.collapse() 不能直接用于 HTML 的原生 window.getSelection() 对象——它根本不存在这个方法。这是最常见的误用起点。
为什么 selection.collapse() 会报错
你调用 getSelection().collapse() 时,浏览器会抛出 TypeError: getSelection(...).collapse is not a function。因为 DOM 的 Selection 接口是只读快照,不提供修改能力;collapse() 是 Word VBA 或 Open XML SDK 中的方法,和 Web API 完全无关。
- Web 端没有
selection.collapse(),只有range.collapse() -
getSelection()返回的是不可变对象,任何试图赋值或调用“修改型方法”的操作都会失败 - 想让光标落到某处且不选中内容,必须通过
Range+removeAllRanges()+addRange()组合实现
正确做法:用 Range.collapse() 模拟“折叠为光标”
核心思路是:先拿到当前选区的 Range,调用它的 collapse(),再用它重置 Selection。
- 必须先检查
selection.rangeCount === 0,否则getRangeAt(0)会触发IndexSizeError -
range.collapse(true)折叠到起点,range.collapse(false)折叠到终点(true/false对应wdCollapseStart/wdCollapseEnd) - 折叠后需显式清除旧选区、添加新 range,否则视觉上可能没变化
const sel = window.getSelection();
if (sel.rangeCount > 0) {
const range = sel.getRangeAt(0);
range.collapse(true); // 折叠到开头
sel.removeAllRanges();
sel.addRange(range);
}
更安全的“清空选区+定位光标”写法
如果目标只是让光标停在某个位置且不选中文字(比如点击后聚焦到段落末尾),不要依赖当前 selection,而是直接构造 range:
立即学习“前端免费学习笔记(深入)”;
- 用
document.createRange()新建 range - 用
range.selectNodeContents(node)或range.setStart(node, offset)定位 - 调用
range.collapse(false)确保是插入点而非选区 - 最后
sel.removeAllRanges(); sel.addRange(range)
特别注意:在 contenteditable 元素外(如普通 <p>)、iframe 跨源、或移动端 Safari 非编辑区域里,getSelection() 可能始终返回空 rangeCount,此时强行操作无意义。
真正容易被忽略的点是:DOM 中不存在“把 selection 折叠掉”这个原子动作。所有看似“折叠”的效果,本质都是“删掉旧选区,塞进一个 collapsed range”。漏掉 removeAllRanges() 或忘记 addRange(),就等于什么都没做。



















