ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

把 note 定位到元素内部:positionAt 的 top-in/right-in/bottom-in 扩展实现(zh.javascript.info 坐标任务实战)

2026/10/8 1:47:53 拓冰建站 浏览量
把 note 定位到元素内部:positionAt 的 top-in/right-in/bottom-in 扩展实现(zh.javascript.info 坐标任务实战) 文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载本篇技术指南基于开源仓库 zh.javascript.info现代 JavaScript 教程中文版中「坐标Coordinates」章节的经典实战任务讲解如何扩展定位函数positionAt(anchor, position, elem)使其不仅能像之前一样把提示元素note放在锚点元素anchor的上方/右侧/下方还能将其精确地插入到锚点元素的内部边缘top-in/right-in/bottom-in。读完本篇你将掌握getBoundingClientRect()与文档坐标document coordinates的换算方法、position:absolute定位的坐标计算原理以及一套可直接复制运行的完整实现。任务背景从元素旁到元素内的定位能力升级在 坐标Coordinates章节 中教程用一组递进式任务来训练元素定位能力position-inside-absolute是这条任务链的最后一环任务一position-at在元素旁显示一个 note —— 实现positionAt(anchor, position, elem)支持top、right、bottom三种外部定位。任务二position-at-absolute在元素旁absolute显示一个 note —— 把 note 的 CSS 从position:fixed改为position:absolute并用getCoords()获取文档坐标解决页面滚动时 note 失控脱离锚点的问题。任务三position-inside-absolute本篇主角把 note 放在元素内部absolute —— 在任务二的基础上新增top-in、right-in、bottom-in三种内部定位。这个任务在实际开发中非常常见tooltip、角标badge、气泡提示、表单校验提示等 UI 元素往往需要既能浮在目标元素外侧也能贴合在目标元素的内边缘。前置知识为什么必须用文档坐标 absolute回顾 坐标章节 的核心结论页面上的任意一点都有两套坐标窗口坐标window / client coordinates从窗口的顶部/左侧边缘计算对应 CSSposition:fixed通过elem.getBoundingClientRect()获取即clientX/clientY。文档坐标document / page coordinates从文档根document root的左上角计算对应 CSSposition:absolute即pageX/pageY。两者通过滚动量换算pageY clientY 垂直滚动出去的高度window.pageYOffsetpageX clientX 水平滚动出去的宽度window.pageXOffset任务二明确指出使用position:fixed时note 固定在窗口位置页面一滚动就会脱离锚点元素。改用position:absolute后需要把窗口坐标加上当前滚动量转换为文档坐标。为此任务二的解决方案 引用了坐标章节的getCoords()辅助函数它正是本任务实现的基石function getCoords(elem) { let box elem.getBoundingClientRect(); return { top: box.top window.pageYOffset, left: box.left window.pageXOffset }; }注意getBoundingClientRect()返回的top/left是窗口坐标可能是小数如10.5甚至负数元素滚出窗口上方时这在设置style.left/top时都不需要额外处理直接拼上px即可。任务要求六种 position 取值本任务要求扩展函数positionAt(anchor, position, elem)把elem插入到anchor内部或旁边position共有六种取值position 取值行为top-out插入到anchor的上方外侧right-out插入到anchor的右侧外侧bottom-out插入到anchor的下方外侧top-in插入到anchor内部贴合上边缘right-in插入到anchor内部贴合右边缘bottom-in插入到anchor内部贴合下边缘前三种*-out与上一个任务行为一致只是把 position 名称从top/right/bottom改成了top-out/right-out/bottom-out后三种*-in是本次新增的能力。任务的调用示例如下// 在 blockquote 上方显示 note positionAt(blockquote, top-out, note); // 在 blockquote 内部的上边缘显示 note positionAt(blockquote, top-in, note);官方要求以 上一个任务position-at-absolute 的解决方案为基础进行扩展因此getCoords()和position:absolute的方案必须保留。完整参考实现仓库 solution.view 源码逐行解析仓库中 solution.view/index.html 提供了完整可运行的标准答案核心逻辑如下function positionAt(anchor, position, elem) { let anchorCoords getCoords(anchor); switch (position) { case top-out: elem.style.left anchorCoords.left px; elem.style.top anchorCoords.top - elem.offsetHeight px; break; case right-out: elem.style.left anchorCoords.left anchor.offsetWidth px; elem.style.top anchorCoords.top px; break; case bottom-out: elem.style.left anchorCoords.left px; elem.style.top anchorCoords.top anchor.offsetHeight px; break; case top-in: elem.style.left anchorCoords.left px; elem.style.top anchorCoords.top px; break; case right-in: elem.style.width 150px; elem.style.left anchorCoords.left anchor.offsetWidth - elem.offsetWidth px; elem.style.top anchorCoords.top px; break; case bottom-in: elem.style.left anchorCoords.left px; elem.style.top anchorCoords.top anchor.offsetHeight - elem.offsetHeight px; break; } }配合 note 的创建与挂载辅助函数showNotefunction showNote(anchor, position, html) { let note document.createElement(div); note.className note; note.innerHTML html; document.body.append(note); positionAt(anchor, position, note); }每种定位的坐标计算原理六个分支都以anchorCoords锚点的文档坐标为基准配合anchor.offsetWidth/anchor.offsetHeight锚点尺寸和elem.offsetHeight/elem.offsetWidthnote 自身尺寸需要先渲染到文档中才有值来计算top-outnote 的左上角对齐锚点左上角纵坐标向上偏移 note 自身高度 →top anchorCoords.top - elem.offsetHeight横坐标left anchorCoords.left。right-outnote 位于锚点右侧横坐标偏移整个锚点宽度 →left anchorCoords.left anchor.offsetWidth纵坐标与锚点顶部对齐。bottom-outnote 位于锚点下方纵坐标偏移整个锚点高度 →top anchorCoords.top anchor.offsetHeight。top-innote 完全贴合锚点内部左上角直接复用锚点坐标 →left anchorCoords.lefttop anchorCoords.top效果等于position:absolute下的left: 0; top: 0。right-innote 贴合锚点内部右边缘需要把 note 的左边缘放在锚点右边缘 - note 自身宽度处 →left anchorCoords.left anchor.offsetWidth - elem.offsetWidth。这里有个实现细节代码先给elem设置了固定宽度elem.style.width 150px确保elem.offsetWidth是可预期的稳定值。bottom-innote 贴合锚点内部下边缘 →top anchorCoords.top anchor.offsetHeight - elem.offsetHeight。可以观察到规律外部定位-out用加法锚点坐标 ± note 尺寸 / 锚点尺寸内部定位-in用减法锚点边缘坐标减去 note 自身尺寸。这正是贴内侧边缘与贴外侧边缘的本质区别。样式与可运行示例note 的样式定义在 solution.view/index.css.note { position: absolute; z-index: 1000; padding: 5px; border: 1px solid black; background: white; text-align: center; font: italic 14px serif; opacity: .8; }其中position: absolute是关键——它的定位上下文是最近的已定位祖先而document.body.append(note)把 note 直接挂到 body 下配合getCoords()给出的文档坐标即可保证页面滚动时 note 始终跟随锚点这正是任务二解决的失控问题。演示页 index.html 的测试代码let blockquote document.querySelector(blockquote); showNote(blockquote, top-in, note top-in); showNote(blockquote, top-out, note top-out); showNote(blockquote, right-out, note right-out); showNote(blockquote, bottom-in, note bottom-in);页面 HTML 的body styleheight: 2000px特意把页面拉高方便验证滚动行为无论页面滚到哪里四个 note 都应始终吸附在 blockquote 的上内侧、上外侧、右侧、下内侧。你可以直接在浏览器中打开该 HTML 文件运行验证。关键要点与易错点结合 任务一的解决方案 和本任务的参考实现有几个必须注意的坑元素必须在文档中才能读取尺寸elem.offsetHeight/elem.offsetWidth只有在元素已经插入文档且非display:none时才有值。这就是为什么showNote里要先document.body.append(note)再调用positionAt。隐藏的或未挂载的元素没有大小坐标计算会全部错位。不要忘记px后缀style.left/top赋值时数值必须拼接px字符串否则会被浏览器忽略。window.pageYOffset / pageXOffsetgetCoords()用它们把窗口坐标转换为文档坐标在旧代码里也常见window.scrollY / window.scrollX两者等价。right-in的固定宽度参考实现给 note 预置了150px宽度使右内贴边计算稳定如果你的 note 内容宽度不固定需要自行保证elem.offsetWidth在计算前已确定。z-index 层级note 需要浮在内容之上.note中的z-index: 1000必不可少否则可能被后续内容遮挡。总结一套可复用的定位能力至此positionAt拥有了完整的六向定位能力三外三内底层依赖的正是 坐标章节 总结的核心结论窗口坐标getBoundingClientRect()适合搭配position:fixed文档坐标getBoundingClientRect() 页面滚动量适合搭配position:absolute。在实际项目中这套getCoordspositionAtshowNote的组合可以直接抽取为通用工具函数把anchor换成任意目标元素、把note换成任意浮层tooltip、下拉面板、校验提示即可获得随页面滚动而稳定跟随、且可内可外的定位能力。赞分享文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载相关推荐在元素内部定位浮层扩展 positionAt 实现 top-in/right-in/bottom-inModern JavaScript Tutorial 坐标实战在元素内部定位浮层扩展 positionAt 实现 top in/right in/bottom inModern JavaScript Tutorial文档/教程前端JavaScript 教程实战实现锚点元素内部定位position-in-absolute——基于 en.javascript.info 坐标系统解析JavaScript 教程实战实现锚点元素内部定位position in absolute——基于 en.javascript.info 坐标系统解析 导文档/教程前端坐标实战用 positionAt 在元素旁精准定位提示框zh.javascript.info 练习题详解坐标实战用 positionAt 在元素旁精准定位提示框zh.javascript.info 练习题详解 本篇文章围绕《现代 JavaScript 教程》文档教程前端上一篇终极指南免费Windows风扇控制软件FanControl完全教程下一篇英雄联盟Akari助手3分钟提升游戏效率的智能工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考