彻底搞懂 offsetX、scrollX、clientX 的区别

本文深入解析前端开发中元素定位的多种属性,如offsetTop、scrollTop、clientTop等,阐述它们的作用及相互之间的区别,并通过实例演示如何运用这些属性进行精准定位。

无论在 iOS 还是前端开发中,关于如何定位一个元素是必须要掌握的知识,而在前端中,元素定位比较难理解,我们今天一起学习下。

在 DOM 设计中,主要通过这些 API 来确定某个元素的具体位置。

offsetTop, offsetLeft, offsetWidth, offsetHeight,

scrollTop, scrollLeft, scrollWidth, scrollHeight,

clientTop, clientLeft, clientWidth, clientHeight,

为什么会有这么多属性来定位一个元素?

我觉得和盒子模型有很大关系,一个盒子就是一个区域,包含 margin、border、padding 和 content。上面 6 个属性可以非常容易定位元素。

有没有类似 iOS 中 frame 的概念?

答案是有的。可以通过 Element.getBoundingClientRect() 来确定元素在可视区域中的位置。

这些属性究竟有什么不同,我们一一分析:

1、offsetX —— 相对谁偏移了多少?

offsetX 是 HTMLElement 的只读属性,不可以修改。offset 有“偏移” 的意思,你可能会把这个属性想成与滚动有关,其实与滚动没半毛钱关系。我们先看 offsetTop 这个属性,它表示当前元素顶部到 offsetParent 节点的距离。这里关键点是 offsetParent,它是指当前元素最近的使用 position 不为 static 的祖先节点,如果没有使用 position 的祖先节点,它的值将是 body 节点(这个值有可能也是 null,如果出现这些极端情况可以查 MDN)。其实关键点是「相对谁偏移了多少的问题」。一图胜千言。

上图中,由于小人的父元素 div 是 positioned,故它的 offsetParent 为 div,而不是 body,offsetTop 是指小人顶部距离 div 距离(图中红线部分)。

同理 offsetLeft 是距离左边的距离,只要明白了 top,left 属性也就明白了。

offsetWidth 和 offsetHeight 指宽高,包含 boder 、 padding 和 content。

总之,offset 相关的属性指元素相对某个元素的位置,与滚动没有半毛钱关系。

2. scrollX —— 滚动了多少?

与 scroll 相关的属性是 Element 的属性,offsetTop、offsetLeft 可读可写,offsetWidth、offsetHeight 只读。

scroll 才真正与滚动相关,我们以竖直方向滚动为例。

只有元素可以滚动 scrollTop 才会有值,否则为 0,也就是说当子元素的高度大于父元素时,设置父元素的 overflow 为 scroll 才会生效。

当 子div 的高度超出 父div 时,父div 需要通过把 overflow 设置为 scroll,这时候 子div 才可以滚动。这里有一点需要注意,图中所标记的 scrollTop 的属性是 子div 的还是 父div 的?欢迎留言说出你的答案。

scrollTop 的值可以修改,表示在滚动区域中,竖直方向滚动了多少。通常通过修改这个值来实现让某个元素滚动到指定位置。

关于 scrollHeight 这个也需要特别留意,父 div 的 scrollHeight 是通过子div 计算的,表示可滚动的高度。

scrollWidth 与 scrollHeight 类似。我特意写了一个 demo,想要搞懂这个必须通过 demo 实践。

3. clientX  —— 我自身的位置

它是 Element 的属性。client 相关的属性描述的是自身的位置,它没有相对元素。

clientTop 就是 border-top 的值,clientLeft 就是 border-left 的值。而 clientWidth 和 clientHeight 都不包含 border。

4. Element.getBoundingClientRect() —— 相对可视区域的位置

通过这个 API 获取元素相对可视区域的位置,返回值是浮点数。其中,大多数情况下 x 与 left 相等,y 与 top 相等,只有当 width 或 height 为负数的时候会有区别。left = x + with,top = y + height。图中黄色区域为边框。

注意观察 bottom 和 right 的值。

5. 少不了 demo

我写了一个输出这些属性的方法,方便同时查看这些属性的值:

var logBySelector = function (id) {
    let elm = document.querySelector(id);
    logFrame(elm);
    elm.onscroll = function () {
        logFrame(elm);
        if (elm.scrollHeight - elm.scrollTop === elm.clientHeight) {
            console.log('到底了');
        }
        else if (elm.scrollTop === 0) {
            console.log('到顶了');
        }
    }
};


var logFrame = function (elm) {
    console.log(elm, '-------------------------');
    console.log(elm.getBoundingClientRect());
    for (key in elm) {
        let whiteList = [
            'offsetTop', 'offsetLeft', 'offsetWidth', 'offsetHeight',
            'scrollTop', 'scrollLeft', 'scrollWidth', 'scrollHeight',
            'clientTop', 'clientLeft', 'clientWidth', 'clientHeight',
            'offsetParent'
        ];
        if (whiteList.indexOf(key) !== -1) {
            console.log(key, ' = ', elm[key]);
        }
    }
}

demo 地址:https://github.com/lefex/FE/tree/master/%E7%AC%AC%E4%BA%94%E9%98%B6%E6%AE%B5

本文讲解了元素相关的位置属性,这几个属性容易弄混,我特意为大家准备了 demo。这些知识与前面讲的 CSS 布局 坚持14天学懂CSS布局(领电子书),盒子模型 第10天:撑起CSS布局的半壁江山---盒子模型 有很大关系。当然我们还需要一节内容来实践一下。大家加油。


推荐阅读:

我是一颗树 · DOM

回到工位“我”悟出了 DOM 设计的精华

打通 DOM 的设计架构

两种方法轻松找到 DOM 元素

YOLOv11人物目标检测数据集 目标类别:['Persona'] 中文类别:['人物'] 训练集:1683 张 验证集:182 张 测试集:0 张 总计:1865 张 该数据集提供了data.yaml文件,内容如下: train: ../train/images val: ../valid/images test: ../test/images nc: 1 names: ['Persona'] YOLOv11城市街头与室内场景人物目标检测数据集 该数据集涵盖了城市街头、商业街区、办公场所及室内生活等多种场景中的人物目标检测,具有广泛的应用价值。通过多样的场景设置和丰富的拍摄角度,能够有效提升模型在复杂环境下的目标识别能力,为智慧城市、安防监控及人机交互等领域提供高质量的训练数据支持。 从数据分布来看,该数据集包含1683张训练集图像、182张验证集图像以及0张测试集图像,整体比例分配合理。训练集与验证集的比例约为9.25:1,能够充分满足模型训练与性能评估的需求,确保模型在不同场景下的泛化能力得到充分验证。 该数据集的标注工作严谨规范,所有图像均经过人工精确标注,每个目标都配有清晰的边界框和统一的标签“Persona”。标注过程遵循严格的标准,确保了数据的高质量和一致性,为后续的模型训练和性能优化提供了可靠的基础。 基于其多样化的场景覆盖和高质量的标注数据,该数据集可广泛应用于智慧城市管理、公共场所安防监控、智能零售分析以及家庭安防等多个领域。特别是在需要精准识别复杂环境中人物的目标检测任务中,该数据集能够显著提升模型的准确性和鲁棒性。
内容概要:本文围绕孤岛微电网的多机协同控制问题,提出了一种融合分层控制架构与事件触发机制的二次控制策略,旨在实现频率和电压的快速恢复。通过Simulink搭建高保真仿真模型,复现了SCI顶刊级别的控制方法,重点攻克传统连续通信模式下通信资源消耗大与控制实时性之间的矛盾。所提出的控制策略在确保系统稳定性和动态响应性能的同时,显著降低了控制器间的通信频率,提升了孤岛微电网的自治能力与运行能效。研究深入探讨了事件触发条件的设计原则及其对系统稳定性的影响,通过大量仿真实验验证了该方法在抗干扰能力、通信优化和控制精度等方面的优越性能。; 适合人群:具备电力系统分析、自动控制理论基础,从事微电网、分布式能源系统、智能配电网等领域研究的研究生、高校科研人员及电力行业工程技术开发者。; 使用场景及目标:① 深入理解孤岛微电网分层控制体系的架构设计与实现逻辑;② 掌握事件触发机制在多智能体协同控制中的建模方法与应用优势;③ 实现频率与电压二次调节的Simulink仿真,对比分析时间触发与事件触发控制策略的性能差异;④ 为高水平学术论文撰写、科研项目申报或工程原型开发提供可复现的技术路径与仿真支持。; 阅读建议:建议结合提供的Simulink仿真模型与配套代码进行动手实践,重点关注控制器参数整定、事件触发阈值设置及仿真结果的动态响应分析,同时可进一步拓展至不同网络拓扑、多能源耦合场景下的鲁棒性测试与优化改进。
内容概要:本文研究了一种兼顾功率均分与电能质量恢复的微电网抗DoS(拒绝服务)攻击的混合动态事件触发二次控制方法,并基于Simulink平台实现了完整的仿真验证。该方法创新性地引入混合动态事件触发机制,在确保控制精度的同时显著降低通信负载,有效缓解资源受限带来的挑战;同时提升了系统对DoS攻击的鲁棒性与容错能力。控制策略在孤岛运行模式下实现了分布式电源间有功与无功功率的精确分配,并保障电压频率等关键电能指标的快速恢复与稳定运行。研究涵盖控制架构设计、稳定性理论分析、抗干扰性能评估及递进式事件触发框架的构建,全面增强了二次协同控制的弹性与实时性。; 适合人群:具备电力系统自动化、微电网控制、网络化控制系统等相关专业知识,从事新能源与智能电网领域科研工作的研究生、高校教师及工程技术人员,尤其适用于关注网络安全与分布式控制融合方向的研究者。; 使用场景及目标:①解决微电网二次控制中通信资源受限与网络安全威胁并存的实际问题;②为抵御DoS攻击导致的控制中断提供高弹性、低开销的协同控制解决方案;③通过Simulink仿真实践深入理解事件触发机制在分布式能源系统中的应用机理与优化潜力。; 阅读建议:此资源以仿真建模为核心手段,不仅呈现控制算法的技术细节,更强调系统级的设计思维与安全韧性考量,建议读者结合理论推导与仿真调试,逐步掌握事件触发策略的参数设计、攻击场景模拟及控制性能评估方法,从而全面提升在复杂网络环境下的微电网控制研究能力。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值