window.getSelection()可随时调用获取Selection对象,无需监听事件;返回对象rangeCount为0表示无选区,非null;跨iframe需在contentWindow上调用,编辑器接管时需配合其API使用。

直接调用 window.getSelection() 就能拿到 Selection 对象
只要页面处于可交互状态(不是 iframe 被 sandbox 阻止、也不在非渲染上下文如 Web Worker 中),window.getSelection() 会立即返回当前文档中用户鼠标或键盘选中的 Selection 对象。它不接受参数,也不需要提前监听——调用即得。
常见错误是误以为它只在 select 事件后才有效;其实任何时候都能调,比如点击按钮时、定时器里、甚至控制台手动执行都行。
- 如果没选中任何内容,返回的
Selection对象rangeCount === 0,但对象本身不为null - 在
<iframe></iframe>内获取选区,必须在对应 iframe 的contentWindow上调用,不能跨域 - 某些编辑器(如 ProseMirror、Slate)会接管原生选区,此时
window.getSelection()可能滞后或被清空,需配合其内部 API 使用
Selection 对象的关键属性怎么看
拿到对象后,最常查的是 anchorNode、focusNode、rangeCount 和 getRangeAt(0)。它们告诉你“从哪开始选、到哪结束、选了几段”。
注意:anchor 是鼠标按下起点,focus 是松开终点,二者顺序可能颠倒(比如反向拖选),所以别假设 anchorNode 一定在前。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
-
selection.rangeCount为 0 → 当前无选区(光标停在某处也算“零长度选区”,但部分浏览器仍返回 1) -
selection.getRangeAt(0)返回Range对象,可用.cloneContents()提取 HTML 片段,或.toString()获取纯文本 - 若选区跨多个不连续区域(如按 Ctrl 多选文本),
rangeCount > 1,但实际网页中极少出现,多数浏览器只支持单段
为什么有时 window.getSelection() 返回空或异常
不是方法失效,而是上下文被干扰。典型场景包括:内容被动态替换、contenteditable 元素失焦、或 selection 被脚本意外清除。
- React/Vue 更新 DOM 后,原生选区大概率丢失——需在更新前用
selection.getRangeAt(0).cloneRange()缓存,更新后再range.select() - 调用
document.execCommand('insertText')或类似操作后,Chrome 有时会重置选区位置,导致后续getSelection()指向错误节点 - 在
blur事件中调用,可能拿到上一次的残留值;应在mouseup或selectionchange事件中取,更可靠
兼容性与移动端注意事项
桌面端现代浏览器全部支持 window.getSelection(),但移动端 Safari 和 Android WebView 行为有差异。
- iOS Safari 在
input或textarea中双击选词后,getSelection()返回的anchorOffset可能不准确(偏移量基于字符而非 DOM 位置) - Android Chrome 对
contenteditable中嵌套inline元素的选区边界计算不稳定,建议用range.getBoundingClientRect()辅助定位 - 不要依赖
Selection对象的构造函数(new Selection())——它不可写,且 MDN 明确标注为只读接口
真正麻烦的从来不是怎么拿到 Selection,而是它随时可能被 DOM 变更、焦点切换或框架劫持悄悄改掉。留心它的生命周期,比记住 API 更重要。

















