
文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载本文以《现代 JavaScript 教程》zh.javascript.info中「查找区域的窗口坐标」任务为骨架完整讲解如何用 DOM API 计算一个带边框元素的四个关键窗口坐标点左上外角、右下外角、左上内角、右下内角并结合仓库中的任务源码与官方解答深入剖析getBoundingClientRect、clientLeft/clientTop、clientWidth/clientHeight等属性的语义差异与适用场景。读完本文你将能够编写出对任意尺寸、任意边框宽度的元素都通用的坐标计算代码并理解如何用点击坐标clientX/clientY对结果进行验证。任务背景在一个绿色区域内定位四个角该任务位于仓库 2-ui/1-document/11-coordinates/1-find-point-coordinates/核心目标是在文档中有一个带有绿色区域field的 iframe用 JavaScript 查找四个角的窗口坐标左上的外角answer1右下的外角answer2左上的内角answer3右下的内角answer4任务的验证方式非常巧妙源页面 source.view/index.html 中内置了一段点击坐标显示脚本点击任意位置都会把e.clientX与e.clientY显示在#coords元素中。你计算出的四个坐标必须与点击对应角时鼠标返回的坐标完全一致才算通过。script document.onclick function(e) { // shows click coordinates coords.innerHTML e.clientX : e.clientY; }; /script也就是说任务要求我们精确复现浏览器在点击那一瞬间得到的窗口坐标clientX/clientY而非文档坐标pageX/pageY。这背后是本章节 坐标 所建立的两套坐标系框架窗口坐标类似position:fixed从窗口顶部/左侧边缘起算与文档坐标类似position:absolute从文档根左上角起算。当页面尚未滚动时二者相等一旦滚动窗口坐标会随之变化文档坐标保持不变。准备阶段任务页面的元素结构先看源视图的样式定义 source.view/index.cssbody { padding: 20px 0 0 20px; cursor: pointer; } #field { overflow: hidden; width: 200px; height: 150px; border-top: 10px solid black; border-right: 10px solid gray; border-bottom: 10px solid gray; border-left: 10px solid black; background-color: #00FF00; font: 10px/1.2 monospace; }关键信息如下#field的内容区尺寸为200px × 150px四边边框各10px左上边框为黑色右下边框为灰色背景为绿色#00FF00这就是题目所说的「绿色区域」body有20px的左内边距与顶部内边距这意味着#field的外角并不贴近窗口原点坐标计算不能依赖恰好从 0 开始的假设。任务的附加要求P.S.明确指出代码不能绑定这些固定值当元素具有其他大小和边框时也必须正确工作。这正是用属性而非写死数字的核心理由。外角计算getBoundingClientRect 一步到位左上的外角与右下的外角最简单直接使用elem.getBoundingClientRect()即可。该方法返回包含元素的最小矩形的窗口坐标结果是一个内建DOMRect类对象主要属性包括x/y—— 矩形原点左上角相对于窗口的 X/Y 坐标width/height—— 矩形的宽高top/bottom—— 顶部/底部边缘的 Y 坐标left/right—— 左/右边缘的 X 坐标。对于getBoundingClientRect()返回的正值矩形派生属性与基本属性满足left x、top y、right x width、bottom y height。下图为该 API 输出的几何示意来源coordinates.svg因此外角代码非常直观let coords elem.getBoundingClientRect(); let answer1 [coords.left, coords.top]; // 左上外角 let answer2 [coords.right, coords.bottom]; // 右下外角left/top天然就是矩形左上角的窗口坐标right/bottom天然就是右下角的窗口坐标。值得注意的是坐标可能是小数如10.5浏览器内部按小数计算这是正常现象无需手工舍入坐标可能是负数——例如页面滚动后元素跑到窗口上方此时top即为负值代码不应假设坐标永远为正。左上内角clientLeft/clientTop 的语义内角与外角的差异完全来自边框宽度。外角是元素 border 的外边缘内角则是 border 的内边缘即 padding 盒的起点。获取边框宽度最可靠的方式是元素的clientLeft/clientTop属性。注意虽然clientLeft的字面意思像客户端左侧但它的语义是「元素边框左边框的宽度」clientTop则是「上边框的高度」。在标准盒子模型下clientLeft恰好等于getComputedStyle(elem).borderLeftWidth的解析值但它是直接暴露的布局属性无需解析样式字符串使用更可靠。let answer3 [coords.left field.clientLeft, coords.top field.clientTop];在本任务的具体数值下field.clientLeft clientTop 10四边边框均为 10px所以左上内角 外角坐标 (10, 10)。而由于任务要求代码对任意边框宽度通用clientLeft/clientTop正是把边框宽度这一未知量交给浏览器计算的最佳方式。右下内角减法方案与加法方案右下内角有两条技术路线官方解答 solution.md 给出了两种方案一CSS 样式解析减法用右下外角坐标减去下边框和右边框的宽度let answer4 [ coords.right - parseInt(getComputedStyle(field).borderRightWidth), coords.bottom - parseInt(getComputedStyle(field).borderBottomWidth) ];这里用getComputedStyle(field).borderRightWidth读取计算后的边框宽度再用parseInt把10px这类带单位字符串转为数字。该方案可行但需要经过读取计算样式 → 解析单位两个步骤略显绕路。方案二从左上内角出发做加法推荐从左上内角坐标出发向右、向下各加上内容区尺寸clientWidth/clientHeightlet answer4 [ coords.left elem.clientLeft elem.clientWidth, coords.top elem.clientTop elem.clientHeight ];为什么说这个方式相较于上一个或许更好原因在于clientWidth/clientHeight表示内容区 padding不含边框的尺寸恰好就是内角的跨度整条链路的每一步都来自浏览器已计算的布局属性getBoundingClientRect、clientLeft/Top、clientWidth/Height没有字符串解析没有隐式类型转换对任意边框与尺寸天然成立这与左上内角公式形成对称answer3 外角 边框answer4 answer3 内容区尺寸逻辑自洽、易于记忆。完整解答在 solution.view/index.html 中可以直接运行验证let fieldCoords field.getBoundingClientRect(); let answer [ [ // 1 左上外角 fieldCoords.left, fieldCoords.top ], [ // 2 右下外角 fieldCoords.right, fieldCoords.bottom ], [ // 3 左上内角 fieldCoords.left field.clientLeft, fieldCoords.top field.clientTop ], [ // 4 右下内角 fieldCoords.left field.clientLeft field.clientWidth, fieldCoords.top field.clientTop field.clientHeight ] ]; alert(answer.join( ));与点击坐标对照为什么clientX/clientY必须一致验证环节要求你计算得到的坐标应该与点击鼠标返回的坐标相同。这里的关键点在于鼠标事件对象中的clientX/clientY恰恰就是窗口坐标——它与getBoundingClientRect()输出的坐标系完全一致都从窗口左上角起算。因此计算出的左上外角(coords.left, coords.top)应与点击元素左上边框外侧时的事件坐标相等计算出的右下内角应与点击内容区右下角内侧时的事件坐标相等。如果把getBoundingClientRect()的结果误当作文档坐标使用例如在页面滚动后与pageX/pageY对照结果就会出现偏差。这正是本章节反复强调的两套坐标系区分窗口坐标适合搭配position:fixed文档坐标适合搭配position:absolute二者通过pageY clientY window.pageYOffset之类的公式换算完整换算函数见 article.md 中的getCoords(elem)示例。延伸从窗口坐标到定位实战掌握四个角的坐标后最常见的落地场景是在元素附近定位浮层。本章节 article.md 提供了createMessageUnder(elem, html)的范例——用getBoundingClientRect()拿到coords.left与coords.bottom再以position:fixed配合style.left/top把消息放在元素正下方注意赋值时务必带上px单位。仓库中 head.html 提供了该示例的可运行版本读者可打开对照学习。如果希望消息在页面滚动时始终跟随元素则需要切换到文档坐标 position:absolute的组合。这个从窗口坐标到文档坐标的跃迁正是本章节下一个任务 在元素旁显示一个 note 的练习内容可作为本任务的进阶延伸。小结目标坐标核心 API公式要点左上外角getBoundingClientRect()[coords.left, coords.top]右下外角getBoundingClientRect()[coords.right, coords.bottom]左上内角clientLeft/clientTop外角 边框宽度右下内角clientWidth/clientHeight左上内角 内容区尺寸四条公式的共同点在于全部基于浏览器计算的布局属性不依赖任何写死的数值因此对任意 size 与 border 的元素都能正确工作。这也是任务 P.S. 的要求——真正的通用坐标代码应当从属性中推导几何信息而非从样式表中猜出答案。赞分享文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载相关推荐JavaScript 教程用 getBoundingClientRect 精确计算元素的窗口坐标外角与内角JavaScript 教程用 getBoundingClientRect 精确计算元素的窗口坐标外角与内角 导读 在编写 Tooltip、弹出提示、拖拽吸文档/教程前端Flutter in_app_purchase 示例应用实战指南从商店配置到端到端购买测试Flutter in_app_purchase 示例应用实战指南从商店配置到端到端购买测试 本篇技术指南以 Flutter 官方维护的 in_app_purc文档教程前端javascript.info 坐标实战用 getBoundingClientRect 与 clientLeft/clientTop 精确计算元素的四角窗口坐标javascript.info 坐标实战用 getBoundingClientRect 与 clientLeft/clientTop 精确计算元素的四角窗口坐文档/教程前端上一篇FUTO Keyboard多语言输入法从英语到藏语Wylie转换器的实现指南 下一篇Gitcoin经济模型分析为什么它正在重塑开源软件的资金生态创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考