把 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),仅供参考

相关新闻

Hyperf 3.0 升级指南:从 PHP8 Attributes 迁移到类型系统重构的完整实践

Hyperf 3.0 升级指南:从 PHP8 Attributes 迁移到类型系统重构的完整实践

后端微服务 【免费下载链接】hyperf 🚀 A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease. 项目地址: https://gitcode.com/gh_mirrors/hy/hyperf 点击查看 免费下载 Hyperf 3.0 是 …

2026/10/12 15:39:45 阅读更多 →
Java Web房屋租赁管理系统源码实战:环境搭建、数据库配置与MVC分层解析

Java Web房屋租赁管理系统源码实战:环境搭建、数据库配置与MVC分层解析

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

2026/10/14 7:28:19 阅读更多 →
Webiny 架构决策解读:ADR-007 转换函数必须返回新值(Transformations Produce New Values)

Webiny 架构决策解读:ADR-007 转换函数必须返回新值(Transformations Produce New Values)

CMS后端前端 【免费下载链接】webiny-js Open-source, self-hosted CMS platform on AWS serverless (Lambda, DynamoDB, S3). TypeScript framework with multi-tenancy, lifecycle hooks, GraphQL API, and AI-assisted development via MCP server. Built for developers at…

2026/10/10 15:09:40 阅读更多 →

最新新闻

用Hermes Agent打造AI数字员工:企业自动化实战全解析

用Hermes Agent打造AI数字员工:企业自动化实战全解析

先交代一下背景,这个教程源自我在某企业内部做的一次 AI 自动化试点总结。当时团队的任务很直接,把重复性高、规则清晰但又需要人肉判断的活儿,逐步交给一套能听指挥、能调用工具、能自己干活的系统。市面上轮子很多,最终敲定用 H…

2026/10/14 23:14:55 阅读更多 →
PyTorch SGD优化器深度解析:动量、weight decay与参数配置实战

PyTorch SGD优化器深度解析:动量、weight decay与参数配置实战

1. 从一个 epoch 的 loss 曲线说起刚接触 PyTorch 那会儿,我写训练脚本基本是抄模板:optimizer torch.optim.SGD(model.parameters(), lr0.01),然后loss.backward()、optimizer.step()、optimizer.zero_grad()三件套走一遍,跑起来…

2026/10/14 23:14:55 阅读更多 →
WebStorm中Vue3+Vitesse项目路径爆红:tsconfig与自动导入声明文件的排查与修复

WebStorm中Vue3+Vitesse项目路径爆红:tsconfig与自动导入声明文件的排查与修复

1. 项目跑得飞起,编辑器却一路飘红:先分辨红线来自谁打开WebStorm,import { useUserStore } from /stores/user下面一条红色波浪线,鼠标移上去是TS2307: Cannot find module /stores/user,可项目在终端里pnpm dev跑得稳…

2026/10/14 23:14:54 阅读更多 →
JSON SyntaxError at position 134 的前端排查与根因分析

JSON SyntaxError at position 134 的前端排查与根因分析

先说让我烦躁的那个瞬间:接口明明返回了 200,网络面板里也看得到数据,前端却红字一片,SyntaxError: Expected , or } after property value in JSON at position 134 (line 1 column 135)。我赌你看到这个报错的第一反应是去翻接口…

2026/10/14 23:14:54 阅读更多 →
Hermes Agent实战:从零搭建AI数字员工实现业务自动化

Hermes Agent实战:从零搭建AI数字员工实现业务自动化

我最早把 Hermes Agent 用进实际业务,是在给一家公司做销售运营自动化的时候。当时团队每天要花两小时人工拉数据、算环比、写简报,我把这套流程拆成几个工具调用和大模型的决策编排,用 Hermes Agent 搭了一个“数字员工”:每天早…

2026/10/14 23:14:54 阅读更多 →
RAG数据预处理:纯Python实现TXT转结构化Markdown,提升检索召回率

RAG数据预处理:纯Python实现TXT转结构化Markdown,提升检索召回率

如果你做过 RAG(检索增强生成)项目,一定遇到过这种窘境:数据拿到手是几百个 txt 文件,没有标题层级,没有段落标记,甚至连编码都不统一。把这种文本丢给 LangChain 或者 LlamaIndex,切…

2026/10/14 23:13:51 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/14 7:53:34 阅读更多 →