const offset = ele => {
let result = {
top: 0,
left: 0,
}
// IE11 以下,直接返回 {top: 0,left: 0}
if(!ele.getClientRects().length) {
return result;
}
// 当前 DOM 节点的 display === 'none' 时,直接返回 {top: 0, left: 0}
if(window.getComputedStyle(ele)['display'] === 'none') {
return result;
}
// 返回元素的大小和它相对于视窗的位置,
// 即,除了大小(width和height)其余的属性都是相对于视窗的左上角位置而言的,
// 所以当存在滚动时,位置有可能是负值,
// 还有一点,这些都是只读属性。
result = ele.getBoundingClientRect();
// Node.ownerDocument 只读属性会返回当前节点的顶层的 document 对象
// documentElement 是根节点
let docElement = ele.ownerDocument.documentElement;
return {
// docElement.clientTop,clientTop 是一个元素顶部边框的宽度,不包括顶部外边距或内边距
top: result.top + window.pageXOffset - docElement.clientTop,
left: result.left + window.pageYOffset - docElement.clientLeft
}
}
测试
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.position_box {
position: relative;
}
.position_inner_box {
width: 200px;
height: 200px;
position: absolute;
top: 20px;
left: 20px;
border: 2px solid #fff;
}
</style>
<body>
<div class="position_box">
<div class="position_inner_box" id="innerBox">
</div>
</div>
</body>
<script type="text/javascript">
const box = document.getElementById('innerBox');
const offset = ele => {
let result = {
top: 0,
left: 0,
}
// IE11 以下,直接返回 {top: 0,left: 0}
if(!ele.getClientRects().length) {
return result;
}
// 当前 DOM 节点的 display === 'none' 时,直接返回 {top: 0, left: 0}
if(window.getComputedStyle(ele)['display'] === 'none') {
return result;
}
// 返回元素的大小和它相对于视窗的位置,
// 即,除了大小(width和height)其余的属性都是相对于视窗的左上角位置而言的,
// 所以当存在滚动时,位置有可能是负值,
// 还有一点,这些都是只读属性。
result = ele.getBoundingClientRect();
// Node.ownerDocument 只读属性会返回当前节点的顶层的 document 对象
// documentElement 是根节点
let docElement = ele.ownerDocument.documentElement;
return {
// docElement.clientTop,clientTop 是一个元素顶部边框的宽度,不包括顶部外边距或内边距
top: result.top + window.pageXOffset - docElement.clientTop,
left: result.left + window.pageYOffset - docElement.clientLeft
}
}
const result1 = offset(box);
console.log(result1)
// {top: 20, left: 20}
</script>
</html>
网友评论