一、js 递归实现

JS 获取元素的 offsetTop, offsetLeft 等属性,可以通过 offsetTop 和 offsetLeft 属性获取元素相对窗口的位置,但 offsetTop 和 offsetLeft 属性都是相对于父元素定位的,而通常需要获取位置的元素都不是在最外层,所以需要遍历上级元素的 offset,递归实现如下。

1
2
3
4
5
6
7
8
9
10
11
12
// 获取元素的纵坐标(相对于窗口)
function getTop(e) {
var offset = e.offsetTop;
if (e.offsetParent !== null) offset += getTop(e.offsetParent);
return offset;
}
// 获取元素的横坐标(相对于窗口)
function getLeft(e) {
var offset = e.offsetLeft;
if (e.offsetParent !== null) offset += getLeft(e.offsetParent);
return offset;
}

二、利用 getBoundingClientRect 实现

很明显前面提到的那种方法效率代价还是比较高的,幸好,现较新的浏览器基本都提供了相应的 API —— getBoundingClientRect

1
2
3
4
5
6
7
8
var box = document.getElementById('box');
var pos = box.getBoundingClientRect();
box.innerHTML = 'top:' + pos.top +
'left:' + pos.left +
'bottom:' + pos.bottom +
'right:' + pos.right +
'width:' + pos.width +
'height:' + pos.height;

注:getBoundingClientRect 兼容性表

`getBoundingClientRect` 兼容性表

https://caniuse.com/#search=getBoundingClientRect