JavaScript Range.compareBoundaryPoints 怎样比较两个范围的端点
来源:17golang原创
时间:2026-10-27 14:25:28 300浏览 收藏
Range.compareBoundaryPoints(how, otherRange) 用来比较两个范围的边界点,结果只有三类:当前范围的指定边界在对方边界之前返回 -1,相同返回 0,之后返回 1。真正容易出错的地方不是返回值,而是四个 how 常量的配对方向,尤其是 END_TO_START。
文档入口:https://developer.mozilla.org/en-US/docs/Web/API/Range/compareBoundaryPoints。下面用同一文本节点建立两个可读的范围,先得到一组稳定的比较基线,再说明偏移单位和适用边界。
- 比较方向始终是“当前 Range 对 otherRange”,不是把两个 Range 交换后再猜结果。
START_TO_END比较当前范围的终点与对方范围的起点;常量名要和映射表一起看。- 这个方法只比较边界点,不能单独回答两个范围是否重叠或是否包含。
先把四种边界配对写成表
可以把调用理解成“从当前 Range 取一个端点,再从 otherRange 取一个端点”。返回值比较的是这两个端点在文档树中的顺序:
| how 常量 | 当前 Range 取值 | otherRange 取值 | 适合表达的关系 |
|---|---|---|---|
START_TO_START | start | start | 两个范围从哪里开始 |
START_TO_END | end | start | 当前范围末端与对方起点 |
END_TO_START | start | end | 当前范围起点与对方末端 |
END_TO_END | end | end | 两个范围在哪里结束 |

表中最值得单独记住的是:常量名的前半段对应当前范围,后半段对应对方范围,但实际比较的端点名称遵循 DOM API 的固定映射,不能凭英文直觉交换。遇到复杂逻辑时,先在代码旁写出“当前端点 → 对方端点”,再调用方法。
用一个可复核的文本节点建立比较基线
下面的两个范围都来自字符串 0123456789。当前范围是 [1, 6),对方范围是 [1, 4);方括号表示包含起点、不包含终点,便于把偏移和字符位置对应起来。
const text = new Text("0123456789");
const currentRange = new Range();
currentRange.setStart(text, 1);
currentRange.setEnd(text, 6);
const otherRange = new Range();
otherRange.setStart(text, 1);
otherRange.setEnd(text, 4);
// 四次调用分别比较起点、交叉端点和终点
const results = {
startToStart: currentRange.compareBoundaryPoints(
Range.START_TO_START, otherRange
),
startToEnd: currentRange.compareBoundaryPoints(
Range.START_TO_END, otherRange
),
endToStart: currentRange.compareBoundaryPoints(
Range.END_TO_START, otherRange
),
endToEnd: currentRange.compareBoundaryPoints(
Range.END_TO_END, otherRange
)
};
// 预期为 { startToStart: 0, startToEnd: 1,
// endToStart: -1, endToEnd: 1 }
console.log(results);
这里 START_TO_START 返回 0,因为两个起点都在偏移 1;START_TO_END 实际比较当前范围终点 6 与对方起点 1,所以返回 1。END_TO_START 比较当前范围起点 1 与对方终点 4,因此返回 -1;最后两个终点是 6 和 4,返回 1。
返回值只说明边界顺序,不直接说明重叠
把返回值翻译成业务判断时,始终使用“当前端点相对于对方端点”的方向。-1 表示当前端点在前,0 表示两个端点相同,1 表示当前端点在后。它类似比较函数的返回约定,不应被理解成距离或重叠长度。

例如两个范围完全分离时,当前范围的终点与对方范围的起点可以用 START_TO_END 观察;但一个可靠的“是否重叠”判断仍需要同时考虑两个范围的起止关系。只看一次比较,无法区分“包含”“被包含”和“部分相交”等情况。
偏移单位和使用边界要先核对
Range 的边界点由节点和偏移组成。对 Text 节点,偏移是文本节点内部的位置;对元素节点,偏移表示子节点序号。不能把一个页面全局字符下标直接当成任意节点的 offset,也不要把 children.length 当作 childNodes.length。
function compareRanges(currentRange, otherRange, how) {
if (!(currentRange instanceof Range) || !(otherRange instanceof Range)) {
// 先拒绝不属于当前文档模型的输入,避免错误藏在比较结果里
throw new TypeError("两个参数都必须是 Range");
}
if (![Range.START_TO_START, Range.START_TO_END,
Range.END_TO_START, Range.END_TO_END].includes(how)) {
// how 不是四个常量之一时,浏览器会抛出 NotSupportedError
throw new TypeError("how 必须是 Range 的比较常量");
}
return currentRange.compareBoundaryPoints(how, otherRange);
}
这个封装只做参数边界说明,不会把返回值改成布尔值,因为调用方还需要知道“前、同、后”。如果目标是 input 或 textarea 内的选区,应使用控件自己的选择接口;如果 DOM 被框架重渲染,旧节点和旧 offset 也可能失效,不能把一次 Range 比较结果当成长期书签。
写判断代码时的检查清单
- 先写清楚当前 Range 和
otherRange,不要在调用前后交换变量。 - 把
how展开成“当前端点 → 对方端点”,尤其检查START_TO_END和END_TO_START。 - 比较前确认两个 Range 的节点和 offset 仍然来自有效的 DOM 状态。
- 需要判断重叠、包含或相邻时,同时检查起点和终点,不用单次返回值替代完整关系判断。
常见问题
返回 0 是不是代表两个 Range 完全相同?
不是。它只代表本次选择的两个边界点相同,例如两个范围的起点相同;终点、包含关系和范围长度仍可能不同。
为什么 END_TO_START 的直觉容易反?
因为 API 的映射固定为当前范围起点对比对方范围终点。把常量名直接当成“当前终点对方起点”会把这一次比较写反,应该以四行对照表为准。
compareBoundaryPoints 能替代重叠检测吗?
不能。它提供端点排序原语;重叠检测还要结合两组起止边界,并考虑范围相邻、包含和折叠等情况。
参考资料:https://developer.mozilla.org/en-US/docs/Web/API/Range/compareBoundaryPoints;方法语义以 DOM Range 规范为准。
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
488 收藏
-
266 收藏
-
486 收藏
-
262 收藏
-
209 收藏
-
406 收藏
-
214 收藏
-
206 收藏
-
138 收藏
-
483 收藏
-
260 收藏
-
118 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习