让你彻底弄清offset

【JavaScript】全面解析offsetLeft、offsetTop 前言:偏移量,很多动画效果的实现都是通过去改变偏移量的改变来实现的,但是你真的完全了解offsetLeft,offsetTop吗? 一、第一个小例子 <body> <style> body { margin:0; } .box1 { width:300px; height:300px; margin:100px; background:#333... 阅读详情

 很多初学者对于JavaScript中的offset、scroll、client一直弄不明白,虽然网上到处都可以看一张图(图1),但这张图太多太杂,并且由于浏览器差异性,图示也不完全正确。

图一

  不知道大家看到这张图的第一感觉如何,反正我的感觉就是“这次第,怎一个乱字了得”。

  既然我认为上图太多太乱,那么我就把offset、scroll、client分开说,希望能让大家彻底弄清楚,今天只说offset。

一、关于offset,我们要弄明白什么

  w3中offset相关页面是:http://www.w3.org/TR/cssom-view/#extensions-to-the-htmlelement-interface

  在这里我们可以看到,关于offset共有5个东西需要弄清楚:

  1、offsetParent

  2、offsetTop

  3、offsetLeft

  4、offsetWidth

  5、offsetHeight

  我们根据难易程度把以上5点分为三类来讲解。

  在分析之前,先来看段测试代码:

<body>
    <style type="text/css">
        body {
            border:20px solid #CCC;
            margin:10px;
            padding:40px;
            background:#EEE;
        }
        #test {
            width:400px;
            height:200px;
            padding:20px;
            background:#F60;
            border:5px solid #888;
        }
    </style>
    <div id="test"></div>
    <script>
        var test = document.getElementById("test");
        test.innerHTML = "<p>Browser:" + navigator.userAgent + "</p>" +
            "<p>offsetWidth:" + test.offsetWidth + "</p>" +
            "<p>offsetHeight:"+test.offsetHeight+"</p>"+
            "<p>offsetLeft:"+test.offsetLeft+"</p>"+
            "<p>offsetTop:"+test.offsetTop+"</p>";
    </script>
</body>

  这段代码在各个浏览器中的效果如图:

图二(IE6/7)

 

图三(IE8/9/10)

 

图四(Firefox)

 

图五(Chrome)

二、offsetWidth与offsetHeight

  大家可以看到,上面图二~图五中的共同点是 offsetWidth与offsetHeight是一致的,因此这里放到地起讲。

  MDN中对offsetWidth的概述和描述是:

Returns the layout width of an element.

Typically, an element's offsetWidth is a measurement which includes the element borders, the element horizontal padding, the element vertical scrollbar (if present, if rendered) and the element CSS width.

  也就是元素的可视宽度,这个宽度包括元素的边框(border),水平padding,垂直滚动条宽度,元素本身宽度等。

  offsetHeight跟offsetWidth类似,只是方向改为垂直方向上的。

  只是我们的示例中没有水平和垂直滚动条。另外经过测试可以发现,即使元素加上水平或垂直滚动条,offsetWidth跟offsetHeight的值是不会更改的,因为浏览器渲染时把滚动条的宽度(或高度)算在了元素本身的宽度(或高度)中了。

  通过代码及图中数值,我们不难看出:

  offsetWidth=(border-width)*2+(padding-left)+(width)+(padding-right)

  offsetHeight=(border-width)*2+(padding-top)+(height)+(padding-bottom)

  对这两个概念就总结到这里,大家现在弄明白了吗?

三、offsetLeft与offsetTop

  offsetWidth与offsetHeight有个特点,就是这两个属性的值只与该元素有关,与周围元素(父级和子级元素无关)。

  然而,offsetLeft与offsetTop却不是这样,这两个属性与offsetParent有关,但在我们讲到offsetParent之前,我们先不管offsetParent是什么及怎么判断,我们只要知道offsetLeft和offsetTop与offsetParent有关就行了,上面的示例中offsetParent就是body。

  MSDN上对offsetLeft的定义是:

Retrieves the calculated left position of the object relative to the layout or coordinate parent, as specified by the offsetParent property

  也就是返回对象元素边界的左上角顶点相对于offsetParent的左上角顶点的水平偏移量。从这个定义中我们可以明确地知道offsetLeft与当前元素的margin-left和offsetParent的padding-left有关。也就是说应该是:

  offsetLeft=(offsetParent的padding-left)+(中间元素的offsetWidth)+(当前元素的margin-left)。

  offsetTop=(offsetParent的padding-top)+(中间元素的offsetHeight)+(当前元素的margin-top)。

  但通过上面的例子我们可以看到,当offsetParent为body时,对于offsetLeft与offsetTop的值有三种,分别是:IE6/7中的40,IE8/9/10 和 Chrome中的70,以及FireFox中的50。

  通过这些数值我们可以知道,当offsetParent为body时情况比较特殊:

  在IE8/9/10及Chrome中,offsetLeft = (body的margin-left)+(body的border-width)+(body的padding-left)+(当前元素的margin-left)。

  在FireFox中,offsetLeft = (body的margin-left)+(body的padding-left)+(当前元素的margin-left)。

四、offsetParent

  终于到offsetParent了。

  offsetParent属性返回一个对象的引用,这个对象是距离调用offsetParent的元素最近的(在包含层次中最靠近的),并且是已进行过CSS定位的容器元素。 如果这个容器元素未进行CSS定位, 则offsetParent属性的取值为根元素的引用。

  总的来说两条规则:

  1、如果当前元素的父级元素没有进行CSS定位(position为absolute或relative),offsetParent为body。

  2、如果当前元素的父级元素中有CSS定位(position为absolute或relative),offsetParent取最近的那个父级元素。

  上面的示例就是第1条说的情况,我们来验证一下:

  我们把JS改为(添加了一行代码:红色部分):

var test = document.getElementById("test");
test.innerHTML = "<p>Browser:" + navigator.userAgent + "</p>" +
    "<p>offsetParent:" + test.offsetParent.tagName + "</p>" +
    "<p>offsetWidth:" + test.offsetWidth + "</p>" +
    "<p>offsetHeight:"+test.offsetHeight+"</p>"+
    "<p>offsetLeft:"+test.offsetLeft+"</p>"+
    "<p>offsetTop:"+test.offsetTop+"</p>";

  FireFox下的效果为:

图六

  在其他浏览器中效果相同,都是body。

  我们再来验证一下第2条,测试HTML如下:

<!DOCTYPE html>
<html>
<head>
    <title>Demo</title>
</head>
<body>
    <style type="text/css">
        body {
            margin:0;
            padding:0;
            background:#EEE;
        }
        div,ul,li {
            margin:0;
        }
        li {
            height:20px;
            line-height:20px;
        }
        #test {
            width:400px;
            height:250px;
            padding:20px;
            background:#F60;
            border:10px solid #888;
        }
        #divtest {
            margin:30px;
            position:relative;
            left:50px;
            top:70px;
            padding:20px;
        }
    </style>
    <div id="divtest">
        <ul>
            <li>Test</li>
            <li>Test</li>
        </ul>
        <div id="test">
        </div>
    </div>
    <script>
var test = document.getElementById("test");
test.innerHTML = "<p>Browser:" + navigator.userAgent + "</p>" +
    "<p>offsetParent:" + test.offsetParent.tagName + "</p>" +
    "<p>offsetWidth:" + test.offsetWidth + "</p>" +
    "<p>offsetHeight:"+test.offsetHeight+"</p>"+
    "<p>offsetLeft:"+test.offsetLeft+"</p>"+
    "<p>offsetTop:"+test.offsetTop+"</p>";
    </script>
</body>
</html>

  在FireFox中效果为:

图七

  在其他浏览器中offsetParent也是一致的。

  在这里我们也可以看到,第三点中给出的offsetLeft的计算公式是适用的。

小结

  以上的总结希望能对大家有所帮助,在看完本文内容后再回过头来看文章开头部分的那张图(只看offset)部分,是不是清楚了很多?

  最后,对于offsetParent为body的情况,现在的主流浏览器IE8/9/10和Chrome及Firefox都跟定义

      offsetLeft=(offsetParent的padding-left)+(中间元素的offsetWidth)+(当前元素的margin-left)。

  offsetTop=(offsetParent的padding-top)+(中间元素的offsetHeight)+(当前元素的margin-top)。

  的不一样,对于这一点我也没有弄明白,如果有朋友知道请不吝赐教。

JavaScript中的offsetWidth属性及其常见用途 在JavaScript编程中,offsetWidth是一种用于获取元素宽度的属性。它返回一个元素的可见宽度,包括元素的内容、内边距和边框的宽度,但不包括外边距。offsetWidth属性可以用于各种情况,例如动态调整布局、计算元素的尺寸和位置,以及响应用户交互等。下面我们将通过一些示例代码来说明offsetWidth属性的常见用途。 阅读详情

相关推荐

浅析offsetLeft,Left,clientLeft之间的区别

主要是对offsetLeft,Left,clientLeft之间的区别进行了详细的分析介绍,需要的朋友可以过来参考下想,希望对大家有所帮助

JS中offsetTop、clientTop、scrollTop、offsetTop各位置属性详解(含示例图)

这里是javascript中制作滚动代码的常用属性 页可见区域宽: document.body.clientWidth; 网页可见区域高: document.body.clientHeight; window.innerHeight; 网页可见区域宽: document.body.offsetWidth (包括边线的宽); 网页可见区域高: document.body.offsetHeight (包括边线的宽); 网页正文全文宽: document.body.scrollWidth; 网页正文全文高..

欢迎来到我的技术博客——一个用代码编织思想的数字花园 🌱 2万+

解决linux 2.5G网卡驱动问题

解决linux 2.5G网卡驱动问题 关键词:2.5G网卡驱动,ubuntu,安装,2.5G Ethernet LINUX driver,Realtek网卡驱动 由于2.5G网卡较新,各linux发行版的通用驱动已不适用,新装的系统会出现无法上网问题,由于国内网络环境去Realtek官网很难下载到驱动文件,故本文提供github上的2.5G Ethernet LINUX driver r8125 for kernel up to 5.6的版本驱动文件r8125-9.003.05.tar.bz2各位可以自

poorguy_aos的博客 1万+

js中offsetHeight,offsetWidth,offsetTop,offsetLeft属性的使用

element.offsetHeight属性返回元素的垂直高度,element.offsetWidth属性返回元素的水平宽度。element.offsetParent属性与定位有着很大的关系,它的定义是:与当前元素最近的经过定位的父级元素。如果存在水平滚动条,offsetHeight包括水平滚动条的高度。offsetLeft表示元素的左外边框至offsetParent元素的左内边框之间的像素距离。offsetTop表示元素的上外边框至offsetParent元素的上内边框之间的像素距离。

m0_56132701的博客 2256

Mellanox CX7网卡搭配400G光模块实战:从选型到部署的完整指南

本文详细解析了Mellanox CX7网卡与400G光模块的选型策略与部署实践,涵盖硬件对比、兼容性验证及性能调优。重点介绍了OSFP光模块的选择要点和常见问题排查方法,帮助用户构建高性能网络基础设施,适用于AI训练、金融交易等场景。

efc1234567的博客 1293

AMEsim不连续处理机制:仿真精度与效率的平衡艺术

本文深入解析AMEsim不连续处理机制在系统仿真中的应用,探讨如何平衡仿真精度与效率。通过液压系统仿真案例,详细介绍了事件检测算法、变步长求解器自适应策略及典型场景优化方法,帮助工程师有效应对仿真中的不连续性问题,提升仿真效率和准确性。

v4w5x6的博客 442

html offset怎么设置,让您彻底弄清offset

很多初学者对于JavaScript中的offset、scroll、client一直弄不明白,虽然网上到处都可以看一张图(图1),但这张图太多太杂,并且由于浏览器差异性,图示也不完全正确。图一不知道大家看到这张图的第一感觉如何,反正我的感觉就是“这次第,怎一个乱字了得”。既然我认为上图太多太乱,那么我就把offset、scroll、client分开说,希望能让大家彻底弄清楚,今天只说offset。一...

weixin_33255691的博客 1270

C语言版数字锁相放大器实现指南:从复数运算到嵌入式MCU移植的坑我都帮你踩了

本文详细介绍了C语言实现数字锁相放大器的关键技术,包括复数运算优化、嵌入式MCU移植的实战经验及内存管理策略。针对STM32等资源受限平台,提供了从浮点到定点数转换的优化方案,帮助工程师高效处理微弱信号提取问题。

weixin_30721077的博客 433

JavaScript:让你彻底弄清offset

ylbtech-JavaScript:让你彻底弄清offset 1.返回顶部 1、  很多初学者对于JavaScript中的offset、scroll、client一直弄不明白,虽然网上到处都可以看一张图(图1),但这张图太多太杂,并且由于浏览器差异性,图示也不完全正确。 图一   不知道大家看到这张图的第一感觉如何,反正我...

weixin_30814223的博客 97

如何在iPhone上本地运行SmolVLM?5亿参数模型实战指南(附Swift代码)

本文详细介绍了如何在iPhone上本地部署和运行轻量高效的SmolVLM多模态模型。通过实战指南,分享了使用Swift和MLX框架进行环境配置、模型加载、内存优化以及实现实时图像分析与文本生成的完整流程,帮助开发者在移动端高效运行AI视觉语言模型。

echo99的专栏 655

Autosar诊断实战系列23-NRC优先级解析

NRC分类,优先级判断逻辑及测试注意事项介绍。

initiallizer的博客 2619

前端攻城狮学习笔记九:让你彻底弄清offset

  很多初学者对于JavaScript中的offset、scroll、client一直弄不明白,虽然网上到处都可以看一张图(图1),但这张图太多太杂,并且由于浏览器差异性,图示也不完全正确。 图一   不知道大家看到这张图的第一感觉如何,反正我的感觉就是“这次第,怎一个乱字了得”。   既然我认为上图太多太乱,那么我就把offset、scroll、client分开说,希望能让大家彻底弄清...

weixin_30521649的博客 1136

高压控制单元与接触器 —— BMS电池的“高压大门”

高压接触器在BMS电池管理系统中扮演着“高压大门”的角色,负责控制电池包与整车高压母线的连接与隔离。接触器的工作原理基于线圈产生的磁力吸合接点,通过主触点接通高压电流路径,辅助触点检测状态,灭弧结构保护接点。预充电路的设计是为了避免直接连接大电容时产生的浪涌电流冲击,通过预充电阻逐步充电,确保系统安全上电。接触器控制策略包括顺序控制、辅助触点检测、温度监控、故障断电和背靠背MOS辅助控制,以确保系统的高效和安全运行。工程师在选择接触器型号、控制线圈、检测状态、软件冗余控制和预充失败保护等方面提供了具体建议。

weixin_43199439的博客 813
上一篇: phpcms模块开发之swfupload上传插件的使用介绍
下一篇: Jquery实现图片放大镜效果的思路及代码
vm021
博客等级 码龄11年 6粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值