盒子模型-坑爹的Offset

11 篇文章 0 订阅

Offset

jQuery@3.5.1 中有一个API,$(el).offset()可以用于获取元素相对于整个网页的左、上边偏移量。
图片截取自MDN
在这里插入图片描述
我们看看jQuery内部是如何实现的。(省去了一些兼容处理,只关注核心API)

offset: function (options) {
            var rect, win,
                elem = this[0];

            if (!elem) {
                return;
            }

            // Get document-relative position by adding viewport scroll to viewport-relative gBCR
            rect = elem.getBoundingClientRect();
            win = elem.ownerDocument.defaultView;
            return {
                top: rect.top + win.pageYOffset,
                left: rect.left + win.pageXOffset
            };
        }

这有两个不太常见的属性
MDN:

Node.ownerDocument 只读属性会返回当前节点的顶层的 document 对象。

Document.defaultView 在浏览器中,该属性返回当前 document 对象所关联的 window 对象,如果没有,会返回 null。

rect = elem.ownerDocument.defaultView; 某种情况下可以看作就是window对象。

Element.getBoundingClientRect()

在这里插入图片描述
原理大概就是这样,当时觉得有点奇怪,不是有一个node.offsetTop吗,为什么非要读取两个属性值?

demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        .parent {
            width: 300px;
            height: 300px;
            background-color: red;
            margin-top: 30px;	/*key value*/
            padding: 10px;		/*key value*/
        }
        .son {
            width: 150px;
            height: 150px;
            background-color: greenyellow;
        }
        html {
            height: 2000px;
        }
    </style>
</head>
<body>
<div class="parent">
    <div class="son"></div>
</div>
<script>
    let son = document.querySelector('.son');
    console.log(`getBoundingClient: ${son.getBoundingClientRect().top}`);
    console.log(`offsetTop: ${son.offsetTop}`);
    console.log(`scrollY: ${window.scrollY}`);
</script>
</body>
</html>

这么一看,好像没有什么问题。
在这里插入图片描述

offsetTop

mdn:
The HTMLElement.offsetTop read-only property returns the distance of the current element relative to the top of the offsetParent node.

offsetParent

HTMLElement.offsetParent 是一个只读属性,返回一个指向最近的(指包含层级上的最近)包含该元素的定位元素或者最近的 table,td,th,body元素。当元素的 style.display 设置为 “none” 时,offsetParent 返回 null。offsetParent 很有用,因为 offsetTop 和 offsetLeft 都是相对于其内边距边界的。

简而言之,offsetLeft会找最近的定位元素或者body元素当作偏移量参考。

我们打印一下sonoffsetParent
在这里插入图片描述
parent加一个position: relative定位
在这里插入图片描述
原来如此…看来offsetLeft/offsetTop使用得小心。

扩展

除了jQuery的解决方法,还有没有其他解决方法?
利用刚才的offsetParent就可以!

注意document.window.offsetParent返回null
在这里插入图片描述
利用这个特性搭配offsetLeft也可以算出左边距。

let parent = son.offsetParent,
    offsetL = son.offsetLeft;

while(parent) {
    offsetL += parent.offsetLeft;
    parent = parent.offsetParent;
}

但是写到这还没完,offsetLeft获取的是外边框到offsetParent的距离,如果offsetParent具有外边框那不是算少了?
我们给parent增加外边框

.parent {
     width: 300px;
     height: 300px;
     border: 20px solid #333;
     background-color: red;
     margin-top: 30px;
     padding: 10px;
     position: relative;
 }

在这里插入图片描述
clientLeft可以获取元素的左边框大小。
利用这个属性完善我们的代码

let parent = son.offsetParent,
    offsetL = son.offsetLeft;

while(parent) {
    offsetL += parent.offsetLeft + parent.clientLeft;
    parent = parent.offsetParent;
}

收工。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
酷客-coidea970开发板用户手册(linux) v1.00坑爹版”问题多多。首先,该版本的用户手册内容混乱,有许多文字错误和排版错误,给用户阅读带来困难。其次,手册中的操作步骤描述不清晰,很难让用户按照指导完成相应的操作。再者,手册中涉及的技术点不够详尽,缺乏实际操作的案例和示范,对用户的学习和使用起不到有效的指导作用。此外,一些重要的功能和配置参数都没有在手册中被提及,导致用户无法充分发挥开发板的性能和功能。最后,该版本的用户手册更新不及时,无法与软件或硬件的最新升级相适应,给用户带来了很大的困扰。 鉴于以上问题,我们建议开发商尽快更新用户手册,修复文字和排版错误,清晰描述操作步骤,详细介绍技术点,并提供丰富的案例和示范。同时,建议手册中加入常见问题解答和故障排除的内容,帮助用户在遇到问题时能够快速定位和解决。另外,建议开发商建立健全的更新机制,及时将软件和硬件升级的信息反馈给用户,确保用户手册的及时性和有效性。 综上所述,“酷客-coidea970开发板用户手册(linux) v1.00坑爹版”的问题令人不满,但我们也相信开发商能够意识到这些问题并尽快采取措施解决。希望在不久的将来,用户能够获得更新完善的用户手册,更好地使用和享受开发板带来的便利和乐趣。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值