写在最前
Selection - Web API | MDN 官方手册
Selection 是什么
直白来说,Selection 是一个用来管理用户文档选择范围的对象。
用户在文档中按住鼠标左键,拖动形成一段蓝底区域便是一个 Range,此时通过下面代码便可获取一个可管理该选择范围的对象。
let selObj = window.getSelection() // 如果没有选中内容,返回一个空的 Selection 对象,not null or undefined
对于某些浏览器(FireFox),可以通过按住 Ctrl 键,选择多个非连续的范围区域。此时通过下面代码可获取具体位置的范围区域。
let range = selObj.getRangeAt(0) // 一般情况下取第一段范围区域
Range 是什么
Range 表示的是用户选区范围,由一对边界点组成,分别定义范围起点和终点。 常用 API:
- setStartBefore(Node): 设置 range 的
边界起点与 Node 的边界起点一致 - setStartAfter(Node): 设置 range 的
边界起点与 Node 的边界终点一致 - setEnd(Node, endOffset): 设置 range 的边界终点,如果 Node 的类型是
Text、Comment或CDATASection之一,那么endOffset指的是从Node边界起点算起字符的偏移量,否则endOffset指的是 Node 第几个childNode,无论是 setStart 还是 setEnd,都是以第几个childNode的边界起点作为目标边界。以下面设置 range 的边界终点为例:
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
</head>
<body>
<div class="content">
<p id="hoge">ひとつめ<span class="second">ふたつめ</span><b>みっつめはふとじ<span>(こども) </span>だよ</b></p>
<p id="fuga">いつつめ<span class="second">むっつめ</span><b>ななつめもふとじ<span>(ななつめのこども)</span>だよ</b></p>
</div>
</body>
<script>
const hoge = document.getElementById("hoge")
const range = new Range()
range.setStart(hoge, 1);
</script>
</html>
常用操作
了解了 selection 和 range 的基本含义后,任何业务功能都可以直接翻阅MDN手册查询能达成自身目的的 api。
比如,要删除实现一个删除用户选中文本的功能,借助 deleteContents 可以这样写:
let sel = window.getSelection()
let range = sel.getRangeAt(0)
range.deleteContents()
又比如,想在选中自定义内容:
let range = new Range()
let content = document.getElementById("select_content_uid")
range.setStart(content)
range.setEnd(content)
let sel = window.getSelection()
sel.removeAllRanges()
sel.addRange(range)
再比如,将光标设置到自定义节点位置:
const node = document.getElementById("target_node_id")
sel.collapse(node, 2)