- 教程
- 文档
【免费下载链接】30-seconds-of-code
Coding articles to level up your development skills
本文围绕 30-seconds-of-code 仓库中的 get-selected-text 文档 展开,讲解如何用一行 JavaScript 代码读取浏览器页面中用户当前选中的文本,并深入Selection对象的原理、边界情况与实战落地(复制选中文本、自定义右键菜单、字数统计等)。读完本文,你将掌握Window.getSelection()/Selection.toString()的完整用法,并能将其与剪贴板操作、选区恢复等进阶技巧组合使用。
核心实现:一行代码读取选中文本
在处理浏览器中的文本时,常常需要获取当前选中的文本,以便实现复制粘贴、文本高亮、自定义上下文菜单等功能。JavaScript 为此提供了Window.getSelection(),它返回一个表示文档中当前选中文本的Selection对象;随后调用Selection.toString()即可拿到实际的文本内容:
const getSelectedText = () => window.getSelection().toString(); getSelectedText(); // 'Lorem ipsum'这就是 30-seconds-of-code 中该代码片段 get-selected-text.md 的完整实现:一个箭头函数,返回window.getSelection().toString()的结果,简洁、可读、开箱即用。
两个关键 API 的角色分工
Window.getSelection():返回一个Selection对象,代表页面中由用户通过鼠标或键盘划定的当前选中区域。它是window上的全局方法,等价于document.getSelection()(该术语被仓库收录在 content/languages/javascript.yaml 的 API 参考表中)。Selection.toString():将选区转换为纯文本字符串。它返回的是选区覆盖文本节点的拼接结果,不含任何 HTML 标签,这与 textcontent-or-innertext.md 中讨论的textContent/innerText语义有本质区别——Selection.toString()的结果更接近"用户真正划选出来的那段文字",而元素文本属性是围绕 DOM 节点的。
两个 API 均在仓库的语言参考文件中被明确登记:Window.getSelection()见 content/languages/javascript.yaml,Selection.toString()见 content/languages/javascript.yaml,说明它们被 30-seconds-of-code 视为浏览器开发的基础能力。
理解Selection对象:从对象到文本的完整链路
Selection是浏览器提供的选区模型,其内部由Range组成:一次选区通常包含一个或多个Range对象(如按住 Ctrl 划选多个区域时会有多个)。Selection.toString()是获取选中文本最快捷的方式,但理解底层结构有助于处理更复杂的场景:
Selection.rangeCount:当前选区的Range数量,0 表示没有选区。Selection.getRangeAt(index):按索引取出对应的Range对象,可进一步获取起止节点与偏移量。
仓库中的进阶示例 copy-text-to-clipboard.md 完整演示了这一套 API 的组合用法:
const selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false; // ...执行复制操作后... if (selected) { document.getSelection().removeAllRanges(); document.getSelection().addRange(selected); }这段代码先通过rangeCount判断是否存在选区,用getRangeAt(0)暂存用户的原始选区,最后用removeAllRanges()与addRange()将其恢复。这正是getSelectedText所在文档末尾备注中提到的"更高级用例":先读取/暂存选区,再操作选区,最后还原选区。对应的Selection.getRangeAt()也在 content/languages/javascript.yaml 中被收录。
实战:把选中文本用起来
getSelectedText()单独使用价值有限,通常要挂在事件里,与业务逻辑组合。以下场景可直接落地:
1. 点击按钮复制选中文本
将getSelectedText与剪贴板 API 组合,用户划选文字后点击按钮即可复制。完整方案见仓库文档 copy-text-to-clipboard.md,其中现代方案基于异步Clipboard API:
const getSelectedText = () => window.getSelection().toString(); const copyToClipboard = str => { if (navigator && navigator.clipboard && navigator.clipboard.writeText) return navigator.clipboard.writeText(str); return Promise.reject('The Clipboard API is not available.'); }; copyButton.addEventListener('click', async () => { await copyToClipboard(getSelectedText()); });注意:剪贴板写入通常要求由用户手势触发,clipboard.writeText()返回 Promise,需要用async/await或.catch()处理失败(如权限拒绝)。
2. 自定义上下文菜单 / 划词提示
监听mouseup或selectionchange事件,实时读取选中文本并渲染自定义菜单:
document.addEventListener('mouseup', () => { const text = window.getSelection().toString(); if (text.trim()) { showCustomMenu(text); // 自定义的划词菜单 } });3. 选中字数 / 字符统计
配合selectionchange或按钮事件,将选中的文本交给String.prototype.length或分词逻辑处理,实现字数统计工具。
边界情况与注意事项
空选区的返回结果
当页面上没有选中任何文本时,window.getSelection().toString()返回空字符串''(而不是null),因此getSelectedText()是安全的,无需额外判空即可直接拼接、统计或传给剪贴板。若需要区分"无选区"与"选中了空文本",可结合rangeCount === 0判断。
输入框内的文本选择
Window.getSelection()只描述页面文档中的选区,<textarea>与<input>内部文本的选中状态不反映在其中。要读取表单控件内的选中文本,应使用HTMLInputElement.selectionStart/selectionEnd或HTMLTextAreaElement上的对应属性,而不是getSelection()。
iframe 与跨文档选区
每个文档拥有独立的选区上下文,window.getSelection()只能拿到当前窗口所在文档的选区;若目标文本位于同源 iframe 内,需要进入该 iframe 的contentDocument再调用其getSelection()。
焦点与选区的区别
需要特别提醒:焦点(focus)和选区(selection)不是一回事。仓库另一篇文档 select-focused-dom-element.md 指出,获取当前聚焦元素应使用document.activeElement(或 CSS 的:focus选择器),而选区指的是内容高亮区域。两者常被混淆,实现"划词"与"获焦"类功能时务必区分。
浏览器兼容与依赖说明
Window.getSelection()与Selection.toString()是标准化多年的 Web API,在现代浏览器中普遍可用;document.getSelection()亦为等价的兼容写法。这与仓库中 copy-text-to-clipboard.md 对 Clipboard API"仍存在兼容性差异、需提供回退方案"的说明不同——读取选区文本无需用户授权,也不受剪贴板权限模型约束,因此getSelectedText可以在任意时机安全调用。该片段属于仓库 browser.yaml 集合 中定义的 "JavaScript Browser Articles" 分类,适用于所有浏览器环境下的 DOM 交互场景。
小结
- 核心一行:
const getSelectedText = () => window.getSelection().toString(); Selection对象通过rangeCount/getRangeAt(index)暴露底层Range,支持选区暂存与恢复。- 读取选中文本常与复制到剪贴板(copy-text-to-clipboard.md)、自定义菜单、字数统计组合使用。
- 注意空选区返回空字符串、输入框文本需走
selectionStart/End、同源 iframe 需切换文档上下文、焦点与选区概念不可混同。
- 教程
- 文档
【免费下载链接】30-seconds-of-code
Coding articles to level up your development skills
相关推荐
30 seconds of code:用 JavaScript 获取当前页面 URL 的完整指南
30 seconds of code:用 JavaScript 获取当前页面 URL 的完整指南 导读 在浏览器端开发中,获取当前页面完整地址是最常见的需求之一
教程文档30 seconds of code:用 `process` 与 `window` 判断当前 JavaScript 环境是 Node.js 还是浏览器
30 seconds of code:用 process 与 window 判断当前 JavaScript 环境是 Node.js 还是浏览器 在浏览器和服务器
教程文档30-seconds-of-code 教程:使用 `git rev-parse --abbrev-ref HEAD` 获取 Git 当前分支名
30 seconds of code 教程:使用 git rev parse abbrev ref HEAD 获取 Git 当前分支名 git rev pars
教程文档
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考