前言:偏移量,很多动画效果的实现都是通过去改变偏移量的改变来实现的,但是你真的完全了解offsetLeft,offsetTop吗?

一、第一个小例子

<body>
<style>body { margin:0;  }.box1 { width:300px; height:300px; margin:100px; background:#333; overflow:hidden; }.box2 { width:200px; height:200px; margin:100px; background:#666; overflow:hidden; }.box3 { width:100px; height:100px; margin:100px; background:#999;}
</style>
<div class="box1"><div class="box2"><div class="box3"></div></div>
</div>
<script>var oBox1 = document.querySelector('.box1');var oBox2 = document.querySelector('.box2');var oBox3 = document.querySelector('.box3');console.log('box1: '+ oBox1.offsetLeft +','+ oBox1.offsetTop);console.log('box2: '+ oBox2.offsetLeft +','+ oBox2.offsetTop);console.log('box3: '+ oBox3.offsetLeft +','+ oBox3.offsetTop);
</script>
</body>

①第一个例子中,三个div的上一级的定位元素都是body,body是最外层的定位元素,三个div获取到的offsetLeft值跟offsetTop值都是相对于body的偏移量。

二、第二个小例子(给box1添加相对定位)

<body>
<style>body { margin:0;  }.box1 { width:300px; height:300px; margin:100px; background:#333; overflow:hidden; position:relative;}.box2 { width:200px; height:200px; margin:100px; background:#666; overflow:hidden; }.box3 { width:100px; height:100px; margin:100px; background:#999;}
</style>
<div class="box1"><div class="box2"><div class="box3"></div></div>
</div>
<script>var oBox1 = document.querySelector('.box1');var oBox2 = document.querySelector('.box2');var oBox3 = document.querySelector('.box3');console.log('box1: '+ oBox1.offsetLeft +','+ oBox1.offsetTop);console.log('box2: '+ oBox2.offsetLeft +','+ oBox2.offsetTop);console.log('box3: '+ oBox3.offsetLeft +','+ oBox3.offsetTop);
</script>
</body>

②第二个例子中,box1加上了相对定位,这时候box2,box3的上一级定位元素不再是body了,这时他们获取到的offsetLeft值跟offsetTop值都是相对于box1的偏移量。而box1的上一级定位元素还是body,所以他的偏移量还是相对于body的。

三、第三个小例子(给box1,box2添加相对定位)

<body>
<style>body { margin:0;  }.box1 { width:300px; height:300px; margin:100px; background:#333; overflow:hidden; position:relative; }.box2 { width:200px; height:200px; margin:100px; background:#666; overflow:hidden; position:relative; }.box3 { width:100px; height:100px; margin:100px; background:#999;}
</style>
<div class="box1"><div class="box2"><div class="box3"></div></div>
</div>
<script>var oBox1 = document.querySelector('.box1');var oBox2 = document.querySelector('.box2');var oBox3 = document.querySelector('.box3');console.log('box1: '+ oBox1.offsetLeft +','+ oBox1.offsetTop);console.log('box2: '+ oBox2.offsetLeft +','+ oBox2.offsetTop);console.log('box3: '+ oBox3.offsetLeft +','+ oBox3.offsetTop);
</script>
</body>

③第三个例子中,box1跟box2都加上了相对定位,这时候,box3的上一级定位元素变成是box2,box2的上一级定位元素是box1,box1的上一级定位元素还是body。所以这时候就出现了。三个div的偏移量都为100;

四、解析

通过上面的三个例子不难看出,offsetLeft值跟offsetTop值的获取跟父级元素没关系,而是跟其上一级的定位元素(除position:static;外的所有定位如fixed,relative,absolute)有关系。

五、扩展(在第三个例子中,假如我想获取到box3到浏览器窗口的偏移量,该怎么去获取呢?)

思路很简单,就是把元素本身的偏移量跟所有上级定位元素的偏移量都加起来就可以了,问题又来了,假如我们不知道他有几个上级定位元素呢?

其实也不难。js不但提供了offsetLeft、offsetTop方法,还提供了offsetParent(获取上一级定位元素对象)的方法。所以现在我们只需封装一个函数就可以了。

function offset(obj,direction){//将top,left首字母大写,并拼接成offsetTop,offsetLeftvar offsetDir = 'offset'+ direction[0].toUpperCase()+direction.substring(1);var realNum = obj[offsetDir];var positionParent = obj.offsetParent;  //获取上一级定位元素对象while(positionParent != null){realNum += positionParent[offsetDir];positionParent = positionParent.offsetParent;}return realNum;
}

运用程序中

<body>
<style>body { margin:0;  }.box1 { width:300px; height:300px; margin:100px; background:#333; overflow:hidden; position:relative; }.box2 { width:200px; height:200px; margin:100px; background:#666; overflow:hidden; position:relative; }.box3 { width:100px; height:100px; margin:100px; background:#999;}
</style>
<div class="box1"><div class="box2"><div class="box3"></div></div>
</div>
<script>var oBox1 = document.querySelector('.box1');var oBox2 = document.querySelector('.box2');var oBox3 = document.querySelector('.box3');function offset(obj,direction){//将top,left首字母大写,并拼接成offsetTop,offsetLeftvar offsetDir = 'offset'+ direction[0].toUpperCase()+direction.substring(1);var realNum = obj[offsetDir];var positionParent = obj.offsetParent;  //获取上一级定位元素对象while(positionParent != null){realNum += positionParent[offsetDir];positionParent = positionParent.offsetParent;}return realNum;}console.log('box1: '+ offset(oBox1,'left') +','+ offset(oBox1,'top'));console.log('box2: '+ offset(oBox2,'left') +','+ offset(oBox2,'top'));console.log('box3: '+ offset(oBox3,'left') +','+ offset(oBox3,'top'));
</script>
</body>

运行结果为:

【JavaScript】全面解析offsetLeft、offsetTop相关推荐

  1. 对于offsetWidth,offsetHeight,offsetLeft,offsetTop的理解

    如何理解区分offsetWidth,offsetHeight,offsetLeft,offsetTop 在刚开始使用的时候总是不能理解这四个有什么不一样,用在哪里,因为这几个词真的太像了,emmm,总 ...

  2. 在JavaScript中解析JSON? [重复]

    本文翻译自:Parse JSON in JavaScript? [duplicate] This question already has answers here : 这个问题已经在这里有了答案 : ...

  3. JavaScript预解析、作用域题目记录

    JavaScript预解析.作用域题目记录 写出以下题目执行的结果及过程分析 function fun ( n ) {console.log( n );var n = 456;console.log( ...

  4. JavaScript(三)—— JavaScript 函数/JavaScript 作用域/JavaScript 预解析/JavaScript 对象

    本篇为 JavaScript 系列笔记第三篇,将陆续更新 JavaScript(一)-- 初识JavaScript/注释/输入输出语句/变量/数据类型 JavaScript(二)-- JavaScri ...

  5. JavaScript 预解析机制

    JavaScript预解析 文章目录 JavaScript预解析 JS预解析? 一.预解析受体 二.对var的预解析 三.对function的预解析 四.var在作用域内 五.function作参.在 ...

  6. 在JavaScript中解析查询字符串[重复]

    本文翻译自:Parse query string in JavaScript [duplicate] Possible Duplicate: 可能重复: How can I get query str ...

  7. 如何在javascript中解析带有两个小数位的浮点数?

    本文翻译自:How to parse float with two decimal places in javascript? I have the following code. 我有以下代码. I ...

  8. 理清offsetparent()、offsetLeft/offsetTop、offset()、position()

    简而言之,它们的概念如下: ① offsetparent() 指的是元素的第一级拥有定位属性(absolute/relative/fixed)的父元素. ② offsetLeft/offsetTop ...

  9. kettle JavaScript JSON解析

    kettle JavaScript JSON解析备注 String转Object var obj = JSON.parse(str) Object 转String var str = JSON.str ...

  10. html页面解析json,JavaScript如何解析json?

    javascript如何解析json?下面本篇文章就来给大家介绍一下使用javascript解析json的方法,希望对大家有所帮助. 什么是JSON?JSON 指的是 JavaScript 对象表示法 ...

最新文章

  1. Android WiFi开发教程(三)——WiFi热点数据传输
  2. 深度学习100例 | 第27天-卷积神经网络(CNN):艺术作品识别
  3. .Net语言 APP开发平台——Smobiler学习日志:如何快速实现类似于微信的悬浮显示二维码效果...
  4. 直播回顾丨神策数据王朋:如何搭建一套高可用的前端异常监控系统?
  5. cfiledialog指定位置和大小_位置度(True Position)中外解读2021(图文+视频)
  6. css语法和JS语法的对比
  7. Java常用类(2)--日期时间相关类Date、Calendar、LocalDateTime、Instant全面
  8. Spring基于XML装配Bean
  9. 云原生持续交付的模式和实践
  10. python函数isdisjoint方法_Python中的isdisjoint()函数
  11. 使用jQuery获取视口大小
  12. 简单实用的下载百度文库文档的方法
  13. 您知道这是什么的,对吧!
  14. 论软件测试工程师面试套路和暗语灵魂解密
  15. 计算机桌面广告弹窗,电脑乱弹广告怎么办_怎么禁止桌面弹出广告
  16. 【蓝桥单片机】51单片机(stc15f)的两个寄存器TCON和TMOD
  17. Android第三方系统有哪些,第三方安卓定制系统LineageOS 14.1支持6款新设备:包括一加3T...
  18. 计算机桌面底下显示条,详细教您电脑屏幕出现条纹怎么办
  19. 2021最火表情包壁纸小程序,全自动一键采集,对接外卖cps,独立后台,无需授权。
  20. jda 沃尔玛_如何通过沃尔玛应用程序的“储蓄守望者”省钱

热门文章

  1. 入门java第一天(1) java介绍(学习笔记)
  2. 页面静态化之FreeMarker技术
  3. [世界24大视觉奇图] 测试你的智商能得多少分?
  4. 【教程】使用ChatGPT制作基于Tkinter的桌面时钟
  5. Twitter 是如何做新版手机网站的
  6. 最高法:侵犯公民个人信息犯罪案件数量显著增长
  7. Python全栈开发之MySQL
  8. 解密conda channels
  9. SAP ABAP 使用BAPI对交货单拣配,发货过账WS_DELIVERY_UPDATE,BAPI_OUTB_DELIVERY_CONFIRM_DEC
  10. html5 滑条 插件,jQuery高性能自定义滚动条美化插件