JavaScript Range.compareBoundaryPoints 怎样比较两个范围的端点
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 规范为准。
JavaScript Range.createContextualFragment 怎样按上下文解析 HTML 片段
- 上一篇
- JavaScript Range.createContextualFragment 怎样按上下文解析 HTML 片段
- 下一篇
- JavaScript TreeWalker.currentNode 怎样从指定节点继续遍历
-
- 文章 · 前端 | 27分钟前 |
- JavaScript HTMLTemplateElement.content 怎样重复实例化模板片段
- 372浏览 收藏
-
- 文章 · 前端 | 30分钟前 | javascript ·
- JavaScript Element.getAnimations 怎样收集子树动画对象
- 243浏览 收藏
-
- 文章 · 前端 | 33分钟前 |
- JavaScript Animation.commitStyles 怎样将动画当前位置写入样式
- 324浏览 收藏
-
- 文章 · 前端 | 38分钟前 |
- JavaScript HTMLSlotElement.assignedElements 怎样读取插槽分配的元素
- 488浏览 收藏
-
- 文章 · 前端 | 43分钟前 |
- JavaScript Document.importNode 怎样复制其他文档的节点树
- 266浏览 收藏
-
- 文章 · 前端 | 45分钟前 |
- JavaScript Document.adoptNode 怎样把节点移入另一个文档
- 486浏览 收藏
-
- 文章 · 前端 | 48分钟前 |
- JavaScript NodeIterator.detach 为什么不应当作释放 DOM 的方案
- 262浏览 收藏
-
- 文章 · 前端 | 48分钟前 | javascript · 前端开发 · JavaScript 前端开发 DOM遍历 TreeWalker currentNode
- JavaScript TreeWalker.currentNode 怎样从指定节点继续遍历
- 209浏览 收藏
-
- 文章 · 前端 | 51分钟前 | range · javascript ·
- JavaScript Range.createContextualFragment 怎样按上下文解析 HTML 片段
- 406浏览 收藏
-
- 文章 · 前端 | 54分钟前 |
- JavaScript Selection.containsNode 怎样判断节点是否处于选区内
- 214浏览 收藏
-
- 文章 · 前端 | 57分钟前 |
- JavaScript Selection.setBaseAndExtent 怎样设置带方向的文本选区
- 206浏览 收藏
-
- 文章 · 前端 | 12小时前 | 前端开发 · CSS 滚动条 可访问性 长列表 scrollbar-width
- CSS scrollbar-width 怎样把长列表滚动条设置为窄版
- 138浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 734次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 736次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 815次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 776次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 611次使用
-
- JavaScript函数定义及示例详解
- 2025-05-11 502浏览
-
- 智能体安全引领产业升级——国内AI安全产品市场深度分析
- 2026-08-21 501浏览
-
- CSS变量简化按钮悬停效果技巧
- 2026-05-31 501浏览
-
- JavaScript符号类型详解与应用
- 2026-05-31 501浏览
-
- HTML剪贴板复制粘贴怎么用
- 2026-05-26 501浏览

