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

发布时间:2026/10/8 1:47:27

把 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),仅供参考
延伸阅读

更多相关文章

2026/10/8 1:42:24

一个超简单的超小型示波器电路

简 介: 本文介绍了一款袖珍型阴极射线管示波器,重量仅850克,体积小巧便携。该示波器采用连续扫描模式,配有10:1探头,可测800V电压,整机功耗7瓦。电路包含四部分:示波管电极偏置电压电路、高压电…

2026/10/8 3:02:34

文字游戏进化之路2.0二开实战:带后台源码部署与改造全解析

很多老站长看到“文字游戏:进化之路2.0二开完美版本源码 带后台”这类标题,第一反应通常是:又来一个割韭菜的。毕竟“完美版本”“带后台”这些词在源码圈早就被用滥了。但如果你真把这套源码拉下来跑一遍,会意外地发现&#xff0…

2026/10/8 3:02:34

工业级3D打印如何重塑制造流程:从桌面级到产线级的关键跃迁

我最早接触3D打印,是在实验室里玩桌面级FDM,打个小船、修个卡扣,图个乐。后来转到生产部门,第一次看到工业级3D打印设备在产线上连续运行两周不停机,我才意识到,工业级3D打印设备根本不是桌面机的“放大版”…

2026/10/8 3:02:34

Hadoop2高可用集群搭建实战:从规划到排错的全流程解析

提到Hadoop集群搭建,尤其是Hadoop2这一代,很多人第一反应是“网上教程多的是,照着敲一遍就行”,但真正落到自己服务器上,总会碰到进程起不来、NameNode切换失败、YARN跑任务卡死这类问题。这篇博文不打算重复那些贴了又…

2026/10/8 3:02:34

订单与库存分布式事务:从强一致到最终一致的方案选型

你见过最诡异的线上事故是什么?我印象最深的,是订单表里突然出现了一批“幽灵订单”:用户明明下单成功,库存扣减却在几毫秒后失败了,等仓库发货时才发现超卖。更隐蔽的是另一类:库存先扣了,订单…

2026/10/8 3:02:34

从Neo4j迁到FalkorDB:实时智能体知识图谱性能跃迁实践

做知识图谱的人应该都刷到过那条消息:FalkorDB号称比Neo4j快496倍。说实话我第一反应是营销号又整活了,但真当我把线上的智能体知识图谱从Neo4j迁到FalkorDB,并在自己的服务器上复现了多跳查询压测之后,我不得不承认,这…

2026/10/8 2:57:34

HDFS底层原理与生产运维实战:从架构到故障排查

写这篇文章之前,我刚帮一位读者排查了一个盘符写满导致的DataNode宕机问题,顺手翻了翻他给的集群监控截图,三副本策略下整整丢了近一小时的写入数据。这不是个例——很多人把HDFS当成一个"能存大文件的分布式硬盘"来用,…

2026/10/5 6:32:56

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/7 8:18:33

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/6 17:46:51

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 0:02:17

自然数立方等于连续奇数之和:从证明到编程验证

十几年来我一直游走在数学科普和编程教学这两块内容之间,对“看起来像魔法、拆开全是数学”的结论总是格外敏感。最近翻资料时又撞见一句话:任何一个自然数 m 的立方,都可以写成 m 个连续奇数之和。2 的立方等于 3 加 5,3 的立方等…

2026/10/8 0:02:17

C#上位机SSH连接实战:用SSH.NET补齐超时、批量与密钥认证

简介:这是一份基于 C# 开发的 SSH 连接功能半成品工程,原本作为另一个主项目的子功能模块,现独立打包分享。工程采用 WinForms 界面,包含源码、解决方案、安装部署工程、NuGet 依赖包及说明文档,适合正在做远程连接、网…

2026/10/8 0:02:17

Java SpringBoot一体化智能售后系统设计与实现全解析

毕业设计年年做,Java Web 方向的题目翻来覆去就那么几个,但“一体化智能售后系统”这个题,每次看到我都觉得值得认真聊一聊。它不是一个简单 curd 堆出来的管理系统,而是把客户、工单、派单、处理、回访、统计整条链路串起来的一套…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑