问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何获得一个dom元素的绝对位置

发布网友 发布时间:2022-04-22 21:51

我来回答

2个回答

懂视网 时间:2022-04-23 02:13

这次给大家带来怎样获取前端界面中的DOM元素绝对位置,怎样获取前端界面中的DOM元素绝对位置的注意事项有哪些,下面就是实战案例,一起来看一下。

在操作页面滚动和动画时经常会获取 DOM 元素的绝对位置,例如 本文 左侧的悬浮导航,当页面滚动到它以前会正常地渲染到文档流中,当页面滚动超过了它的位置,就会始终悬浮在左侧。

本文会详述各种获取 DOM 元素绝对位置 的方法以及对应的兼容性。关于如何获取 DOM 元素高度和滚动高度,请参考视口的宽高与滚动高度 一文。

概述

这些是本文涉及的 API 对应的文档和标准,供查阅:

API用途文档标准
offsetTop相对定位容器的位置MDNCSSOM View Module
clientTop上边框宽度MDNCSSOM View Module
.getBoundingClientRect()元素大小和相对视口的位置MDNCSSOM View Module
.getClientRects()所有子 CSS 盒子的大小和位置MDNCSSOM View Module
.getComputedStyle()应用所有样式表和计算之后的 CSS 属性MDNDOM Level 2 Style CSSOM

offsetTop/offsetLeft

HTMLElement.offsetTop 用来获取当前元素(不包括上边框)相对于定位容器(positioning container)的位置。也就是说,

如果所有祖先元素都是静态定位 position:static;(这是默认的情况),offsetTop 表示与文档最上方的高度差(文档最上方可能已经滚出视口,这个高度可能大于视口高度)。

如果存在绝对定位的祖先元素 position:absolute/fixedoffsetTop 就会相对于这个元素。因此为了获取相对于文档最上方的高度差,需要递归地调用:

function getOffsetTop(el){
 return el.offsetParent
 ? el.offsetTop + getOffsetTop(el.offsetParent)
 : el.offsetTop
}

el.offsetParent 是当前元素的定位容器(positioning container),如果当前元素没有绝对定位的祖先节点,这个属性的值就是 null

兼容性和限制:几乎所有浏览器都支持该属性。如果元素被隐藏它的值就是 0,但在 IE9 下没有影响。

clientTop/clientLeft

不要被名字误导,Element.clientTop 是指当前元素的 上边框的宽度 的整数值。总是等于 getComputedStyle() 返回的 border-top-width 属性的四舍五入为整数后的值。

为什么呢?在 DOM 术语中,client 总是指除边框(border)外的渲染盒子(内边距+内容大小)。offset 总是指包含边框的渲染盒子(边框+内边距+内容大小),clientTop 即为这两者的 Top 之差,即边框宽度。盒子的概念请参考:CSS Display 属性与盒模型

兼容性和限制:同 offsetTop/offsetLeft

.getBoundingClientRect()

Element.getBoundingClientRect() 用于获取元素的大小,以及相对于视口(viewport)的位置,返回一个 DOMRect 对象。

> document.querySelector('span').getBoundingClientRect()
DOMRect {x: 2.890625, y: 218.890625, width: 1264, height: 110, top: 218.890625, …}
bottom: 328.890625
height: 110
left: 2.890625
right: 1266.890625
top: 218.890625
width: 1264
x: 2.890625
y: 218.890625

如果要获取相对于文档左上角的位置,需要在上述 topleft 的基础上再加滚动位置。如下代码来自 MDN,可兼容几乎所有浏览器:

// For scrollX
(((t = document.documentElement) || (t = document.body.parentNode))
 && typeof t.scrollLeft == 'number' ? t : document.body).scrollLeft
// For scrollY
(((t = document.documentElement) || (t = document.body.parentNode))
 && typeof t.scrollTop == 'number' ? t : document.body).scrollTop

兼容性和限制:同样是 CSSOM View Module 的特性,但几乎兼容所有浏览器,可参考

https://caniuse.com/#feat=getboundingclientrectIE 下窗口的左上角可能不是 0,0,在 IE9 可以这样把它设置为 0,0:

<meta http-equiv="x-ua-compatible" content="ie=edge"/>

.getClientRects()

Element.getClientRects() 用来获得 DOM 元素中的所有CSS 盒模型 对应的 DOMRect 组成的集合。

如果是一个块级元素,返回的集合中应该只有一个元素,即这个块的大小和位置。但如果是一个行内元素(或者 SVG 内的元素),则会返回其中每个 CSS 盒子。比如一个普通的被默认折行的 <span>

> document.querySelector('span').getClientRects()
DOMRectList {0: DOMRect, 1: DOMRect, 2: DOMRect, length: 5}
0: DOMRect {x: 2.890625, y: 262.890625, width: 1264, height: 22, top: 262.890625, …}
1: DOMRect {x: 2.890625, y: 284.890625, width: 1264, height: 22, top: 284.890625, …}
2: DOMRect {x: 2.890625, y: 306.890625, width: 768, height: 22, top: 306.890625, …}

这个 <span> 有三行,其中第三行的长度不足一行,每次折行都形成了一个新的 CSS 盒子。

兼容性和限制:在 IE8 及以下会返回 IE 独有的 TextRectangle 对象(而不是 ClientRect),这个对象不具有 widthheight 属性,而且无法给它设置属性。参考:https://webplatform.github.io/docs/dom/HTMLElement/getClientRects/

.getComputedStyle()

Window.getComputedStyle() 可以得到一个元素的所有计算后的 CSS 属性。对于简单的绝对定位元素,可以通过这个 API 返回的 topleft 等属性值获取元素的位置。例如:

let btn = document.querySelector('#btn-scroll-up')
let {top, left} = getComputedStyle(btn)
console.log('top:', top, 'left:', left)

.getComputedStyle() 还有一个有用的用法,获取伪元素的大小和位置等样式信息:

// 以下代码来自: https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
var h3 = document.querySelector('h3'); 
var result = getComputedStyle(h3, ':after').content;
console.log('the generated content is: ', result); // returns ' rocks!'

兼容性和限制:.getComputedStyle() 几乎兼容所有浏览器,可参考 https://caniuse.com/#search=getComputedStyle。但它返回的值是 CSS 属性,用它获取绝对位置时要注意值的类型。例如 left 可能是 13px 这样的绝对值,也可能是 auto 这样的 CSS 关键字。

总结 获取 DOM 元素相对于文档的位置,可以直接使用 offsetTop; 获取 DOM 元素相对于视口的位置,可以使用 .getBoundingClientRect(); 获取 SVG 元素或行内元素的 CSS 盒子(比如用来做文本高亮时),可以使用 .getClientRects(); 获取绝对定位元素、伪元素的渲染后 CSS 属性,可以使用 .getComputedStyle()

相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

推荐阅读:

JS的try-catch语句与错误类型使用

如何操作将配置数据从代码中分离

热心网友 时间:2022-04-22 23:21

document.getElementById("id");
或者 document.getElementByName("name")[i] 得到的是个数组,包括所有名字为name的元素。
或者 getElementsByTagName() 方法可返回带有指定标签名的对象的集合
还有parentNode、firstChild以及lastChild
分别是元素的 父节点,第一个孩子节点,最后一个孩子节点。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
哥们,我是黑龙江齐齐哈尔现在高一的,想报考中国刑警学院,什么分数线啊... 没有驾驶证车辆查到有违章怎么办 广州岭南印象园景区介绍 ...从新选像我这样的人不知道读什么又懒又不想背书。 哎呀哎呀好烦阿要期末考试了,我不想背书 高考我是文科的光不想背书怎么办呢 我不想背书啊啊啊啊,考第一真难,现在的初中生涯好难熬,哪位大神教我... 现在初二了 不想背书 感觉好无聊 只想玩 但是成绩还是不错的 我该... ...时候学习还中等。现在基本一窍不通。也不想背书,身边也没人背,上课... [精选]菊花茶的副作用 iphone4按键贴怎么去胶 什么办法可以把home键贴撕下来 苹果返回键上的贴图怎么拿下来 home键贴怎么取下来 苹果手机按键上粘上装饰品后怎么去掉 苹果Home键上贴了按键贴有什么办法取下来? 要不伤害手机。 求大神指点。 ipad上的home键贴纸贴了快半年了 现在扣不不下来了 有办法弄下来吗? 按键贴怎么取下来 西门子冰箱和松下冰箱和海尔冰箱到底买哪个?头疼 公交卡算不算nfc标签 女孩经常吃避孕药有什么后遗症么? 紧急避孕药 IC卡和nfc卡究竟选哪个 林嗣环的《口技》翻译 七年级下学期语文课文 口技 翻译,恳求各位帮帮忙,急急急 可否用英语来表演京剧? 春雨的诗句韩愈 一段关于京剧的日语求翻译 英语翻译 京剧被誉为“东方歌剧”, 是地道的中国国粹。它起源于中国多种古老的地方戏剧,特别是南方的 日文翻译:谁能帮我翻译下这几段日文,是发表会的演员采访,别用翻译器。 OPPO手机相机插件怎么添加? oppo手机的相机插件丢失,有什么解决方法? 做饭铁锅放入去水垢粉锅里掉黑色,如何解决? 做饭铁锅外多年的残留怎么处理 炒菜做饭铁锅好还是不绣钢锅好 读书郎手表w2c sos怎么用? 电饭铁锅里的饭可以放到明天吗? 做饭铁锅 为啥老生锈,好多办法都试过了,依然没解决 回家呷饭铁锅鸡做法 五六十年代的做饭铁锅 宾阳县哪里有木桶饭砂锅饭铁锅饭之类的再宾阳县城里的 怎么买ipod classic80g的充电器+数据线+硅胶套 我手机OPPOR7plus被恶意软件锁了,我有指纹解锁,可以打开手机。但是手机密码不知道了怎么解? 供应门窗密封条、硅橡胶密封条、胶管螺旋保护套和高品质减震器橡胶制品的厂家中,哪家的产品口碑好? 最近想入手PSP3000 不知道现在破解情况如何了!我对PSP 了解很少 希望达人能为我解惑! 你要买PSP吗?我有一个PSP3000,6.2破解 8G棒子 原充原数据线 硅胶套 给参考一下这款手机 商务人员应具备哪些素质?谁具体的说明下 浏览器的原点位置在哪?如何确定坐标? 元素的绝对定位和相对定位的区别是什么?请举个通俗的例子。 中了10张维尔发债。有多少价值?