前言:这是笔者学习之后自己的理解与整理。如果有错误或者疑问的地方,请大家指正,我会持续更新!

偏移量

  偏移量(offset dimension)是 javascript 中的一个重要的概念。涉及到偏移量的主要是offsetLeft、offsetTop、offsetHeight、offsetWidth这四个属性,还有一个偏移参照,定位父级 offsetParent。

定位父级

  定位父级 offsetParent 的意思是:与当前元素最近的拥有 position 不等于 static 的父级元素,主要分为下列几种情况:

  • 元素自身有 fixed 固定定位时,我们知道固定定位的元素相对于视口进行定位,此时没有定位父级,offsetParent的结果为 null;firefox浏览器有兼容性问题,返回body
  • 元素自身无 fixed 定位,且父级元素都没有 position 定位过,offsetParent 的结果为<body>;
  • 元素自身无 fixed 定位,且父级元素存在拥有 position 不等于 static 的元素,offsetParent 的结果为就是这个元素;
  • <body>元素自身的 parentNode 是null;
  1. <div id="wrapper" style="position: fixed;">
  2. <div id="testa"></div>
  3. </div>
  4.  
  5. <div id="outer" style="position: relative;">
  6. <div id="inner" style="position: absolute;">
  7. <div id="testb"></div>
  8. </div>
  9. </div>
  10.  
  11. <div id="testc"></div>
  12. <script type="text/javascript">
  13. var oWrapper = document.getElementById('wrapper');
  14. var oTestA = document.getElementById('testa');
  15.  
  16. //元素自身有 fixed 固定定位时,offsetParent的结果为 null;firefox浏览器返回body
  17. console.log(oWrapper.offsetParent);//null
  18. //元素自身无 fixed 定位,且父级元素存在拥有 position 不等于 static 的元素,offsetParent 的结果为就是这个元素;
  19. console.log(oTestA.offsetParent);//<div id="wrapper" style="position: fixed;">...</div>
  20.  
  21. var oOutter = document.getElementById('outer');
  22. var oInner = document.getElementById('inner');
  23. var oTestB = document.getElementById('testb');
  24.  
  25. //元素自身无 fixed 定位,且父级元素都没有 position 定位过,offsetParent 的结果为<body>;
  26. console.log(oOutter.offsetParent);//body
  27. //元素自身无 fixed 定位,且父级元素存在拥有 position 不等于 static 的元素,offsetParent 的结果为就是这个元素;
  28. console.log(oInner.offsetParent);//<div id="outer" style="position: relative;">...</div>
  29. console.log(oTestB.offsetParent);//<div id="inner" style="position: absolute;">...</div>
  30.  
  31. var oTestC = document.getElementById('testc');
  32. //元素自身无 fixed 定位,且父级元素都没有 position 定位过,offsetParent 的结果为<body>;
  33. console.log(oTestC.offsetParent);//body
  34.  
  35. var oBody = document.getElementsByTagName('body')[0];
  36. //<body>元素自身的 parentNode 是null;
  37. console.log(oBody.offsetParent);//null
  38. </script>

偏移量大小

  偏移量共包括 offsetWidth、offsetHeight、offsetLeft、offsetTop 这四个属性;

offsetWidth

  offsetWidth 表示元素在水平方向上占用的空间大小(不包括margin),无单位(以像素px计);

  offsetWidth = border + width + padding

offsetHeight

  offsetHeight 表示元素在垂直方向上占用的空间大小(不包括margin),无单位(以像素px计);

  offsetHeight = border + Height+ padding

  如果存在滚动条,offsetWidth/offsetHeight 也包括滚动条的距离;

  浏览器一般把垂直滚动条的宽度从width宽度中移出,把水平滚动条的高度从height高度中移出,则滚动条宽度为17px,width 宽度和 height 高度为剩下的83px,

  IE8及以下浏览器将垂直滚动条的宽度计算在 width 宽度和 height 高度中;

offsetTop 与 offsetLeft

  offsetTop/offsetLeft 表示当前元素与 offsetParent 元素的 border 之间的像素距离(当前元素的 margin + offsetParent 元素的 padding);

  如果当前元素设置了 position 与 left/top ,那么 offsetTop/offsetLeft = 当前元素的left/top + 当前元素的margin ;

  position 与 left/right/top/bottom 方位属性配合,显示的是当前元素的 margin 外侧到 offsetParent 元素的 border 内侧之间的距离;

  如果父级都没有定位则以 body 为准。

  IE7及以下浏览器在 offsetTop 属性的处理上存在bug:

  1. 若父级设置 position: relative,则在IE7及以下浏览器下,offsetTop 值为 offsetParent 元素的 padding-bottom 值;
  2. 若父级设置 position: aboslute(或其他触发 haslayout 的条件),offsetTop 值为 offsetParent 元素的 padding-bottom 值和当前元素的 margin-top 值的较大值;
  1. <style type="text/css">
  2. *{padding: 0;margin: 0;}
  3. #wrapper{
  4. position: relative;
  5. width: 400px;
  6. height: 400px;
  7. padding: 30px;
  8. border-width: 10px;
  9. margin: 20px;
  10. border-color: #ff0;
  11. border-style: solid;
  12. background-color: #333;
  13. }
  14. #test{
  15. position: absolute;
  16. left: 100px;
  17. top: 100px;
  18. width: 100px;
  19. height: 150px;
  20. padding: 20px 30px 40px 50px;/*上右下左*/
  21. border-width: 50px 30px 40px 20px;
  22. margin: 30px 50px 20px 40px;
  23. border-color: #f0f;
  24. border-style: solid;
  25. background-color: #0ff;
  26. }
  27. </style>
  28. <div id="wrapper">
  29. <div id="test"></div>
  30. </div>
  31. <script>
  32. var oTest= document.getElementById('test');
  33.  
  34. //offsetWidth = border-left + border-right + width + padding-left + padding-right
  35. //230=30+20+100+30+50
  36. console.log(oTest.offsetWidth);//230
  37.  
  38. //offsetHeight = border-top + border-bottom + width + padding-top + padding-bottom
  39. //300=50+40+150+20+40
  40. console.log(oTest.offsetHeight);//300
  41.  
  42. //offsetTop 表示元素的上外边距至 offsetParent 元素的上内边距之间的像素距离;
  43. //60=30+100
  44. console.log(oTest.offsetTop);// 130
  45.  
  46. //offsetLeft 表示元素的左外边距至 offsetParent 元素的左内边距之间的像素距离;
  47. //70=40+100
  48. console.log(oTest.offsetLeft);// 140
  49. </script>

页面偏移

  要知道某个元素在页面上的偏移量,将这个元素的 offsetLeft/offsetTop 与其 offsetParent 的 offsetLeft/offsetTop 相加,并加上 offsetParent 的相应方向的边框border,如此循环直到根元素,就可以得到元素到页面的偏移量;

  在默认情况下,IE8及以下浏览器下如果使用 currentStyle() 方法获取<html>和<body>(甚至普通div元素)的边框宽度都是medium,而如果使用 clientLeft/clientTop 获取边框宽度,则是实际的数值;

  1. <style type="text/css">
  2. *{padding: 0;margin: 0;}
  3. #wrapper{
  4. position: relative;
  5. width: 400px;
  6. height: 400px;
  7. padding: 30px;
  8. border-width: 10px;
  9. margin: 20px;
  10. border-color: #ff0;
  11. border-style: solid;
  12. background-color: #333;
  13. }
  14. #test{
  15. position: absolute;
  16. width: 100px;
  17. height: 150px;
  18. padding: 20px 30px 40px 50px;/*上右下左*/
  19. border-width: 50px 30px 40px 20px;
  20. margin: 30px 50px 20px 40px;
  21. border-color: #f0f;
  22. border-style: solid;
  23. background-color: #0ff;
  24. }
  25. </style>
  26. <div id="wrapper">
  27. <div id="test"></div>
  28. </div>
  29. <script>
  30. function getElementLeft(obj){
  31. var actualLeft = obj.offsetLeft;
  32. var current = obj.offsetParent;
  33. while(current != null){
  34. actualLeft += current.offsetLeft + current.clientLeft;
  35. current = current.offsetParent;
  36. }
  37. return actualLeft + 'px';
  38. }
  39. function getElementTop(obj){
  40. var actualTop = obj.offsetTop;
  41. var current = obj.offsetParent;
  42. while(current != null){
  43. actualTop += current.offsetTop + current.clientTop;
  44. current = current.offsetParent;
  45. }
  46. return actualTop + 'px';
  47. }
  48.  
  49. var oWrapper= document.getElementById('wrapper');
  50. var oTest= document.getElementById('test');
  51.  
  52. console.log(oWrapper.offsetLeft);//20
  53. console.log(oTest.offsetLeft);//70
  54. //100=70+20+10
  55. console.log(getElementLeft(oTest));//100px
  56.  
  57. console.log(oWrapper.offsetTop);//20
  58. console.log(oTest.offsetTop);//60
  59. //90=60+20+10
  60. console.log(getElementTop(oTest));//90px
  61. </script>

客户区

  客户区大小 client 指的是元素内容及其内边距所占据的空间大小;

  盒子调用,指盒子本身;body/html调用,指可视区域大小。

  clientWidth 属性返回元素节点的客户区宽度;clientWidth = padding + width

  clientHeight 属性返回元素节点的客户区高度;clientHeight = padding + height

  滚动条宽度不计算在内;

  clientLeft 属性返回左边框的宽度;

  clientTop 属性返回上边框的宽度;

  如果 display 为 inline 时,clientHeight、clientWidth、clientLeft 和 clientTop 属性都返回0;

  1. <div id="divTest" style="width: 100px;height: 100px;padding: 10px;margin: 10px;border: 1px solid black;"></div>
  2. <span id="spanTest" style="width: 100px;height: 100px;padding: 10px;margin: 10px;border: 1px solid black;"></span>
  3. <script>
  4. var oDivTest = document.getElementById('divTest');
  5. var oSpanTest = document.getElementById('spanTest');
  6. //120(10+100+10)
  7. console.log(oDivTest.clientHeight);//120
  8. console.log(oDivTest.clientWidth);//120
  9.  
  10. console.log(oDivTest.clientLeft);//1
  11. console.log(oDivTest.clientTop);//1
  12.  
  13. //如果 display 为inline 时,clientHeight、clientWidth、clientLeft和clientTop属性属性都返回0
  14. console.log(oSpanTest.clientHeight);//0
  15. console.log(oSpanTest.clientWidth);//0
  16. console.log(oSpanTest.clientLeft);//0
  17. console.log(oSpanTest.clientTop);//0
  18. </script>

页面大小

  常用 document.documentElement.clientWidth/clientHeight 属性来表示可视区域页面大小(不包含滚动条宽度);

  另一个对常用的表示页面大小的属性是 window.innerHeight/innerWidth 属性(包含滚动条宽度);

  innerHeight 和 innerWidth 表示的是浏览器窗口大小减去菜单栏、地址栏等剩余的页面尺寸,由于滚动条是属于页面的,所以包含滚动条;

  IE8及以下浏览器不支持 innerHeight 和 innerWidth 属性;

  如果没有滚动条(页面最大化),这两类属性在电脑端表示同样的值,但是却表示不同的含义。在移动端,innerWidth 和 innerHeight 表示的是视觉视口,即用户正在看到的网站的区域;而document.documentElement.clientWidth 和 clientHeight 表示的是布局视口,指CSS布局的尺寸。

  1. <body style="overflow:scroll">
  2. <script>
  3. //1349=1366-17
  4. console.log(document.documentElement.clientWidth);
  5. //621=638-17
  6. console.log(document.documentElement.clientHeight);
  7.  
  8. console.log(window.innerWidth);//1366
  9. console.log(window.innerHeight);//638
  10. </script>
  11. </body>

clientX 和 clientY

  event 对象是 JavaScript 中最重要的对象之一,它代表了各种事件的状态,在各种事件的事件处理中经常用到,比如键盘活动、鼠标活动等等;

  clientX,鼠标指针位置相对于窗口客户区域的 x 坐标,(event调用); 其中客户区域不包括窗口自身的控件和滚动条;

  clientY,鼠标指针位置相对于窗口客户区域的 y 坐标,(event调用); 其中客户区域不包括窗口自身的控件和滚动条;

  offsetX,鼠标指针位置相对于触发事件的对象的 x 坐标;

  offsetY,鼠标指针位置相对于触发事件的对象的 y 坐标;

  screenX,鼠标指针位置相对于用户屏幕的 x 坐标;

  screenY,鼠标指针位置相对于用户屏幕的 y 坐标;

  1. <style type="text/css">
  2. *{padding: 0;margin: 0;}
  3. body{height: 1000px;}
  4. p{height: 300px;width: 300px;background: #f0f;}
  5. </style>
  6. <body>
  7. <p>请在文档中点击。控制台会提示出鼠标指针的 x 和 y 坐标。</p>
  8.  
  9. <script type="text/javascript">
  10. var oBody = document.getElementsByTagName('body')[0];
  11. var oP = document.getElementsByTagName('p')[0];
  12. oBody.onmousedown = function(ev){
  13. ev = ev || event;
  14.  
  15. clX = ev.clientX;
  16. clY = ev.clientY;
  17. console.log("鼠标clientX的值是: " + clX + ", 鼠标clientY的值是: " + clY);
  18.  
  19. scX = ev.screenX;
  20. scY = ev.screenY;
  21. console.log("鼠标screenX的值是: " + scX + ", 鼠标screenY的值是: " + scY);
  22. }
  23.  
  24. oP.onmousedown = function(ev){
  25. ev = ev || event;
  26.  
  27. ofX = ev.offsetX;
  28. ofY = ev.offsetY;
  29. console.log("鼠标相对于p标签的offsetX的值是: " + ofX + ", 鼠标相对于p标签的offsetY的值是: " + ofY);
  30. }
  31. </script>
  32. </body>

jacascript 偏移量offset、客户区client的更多相关文章

  1. MFC自绘框架窗口客户区

    利用MFC开发用户界面往往需要需要根据要求进行界面美化,界面的美化包括很多内容,比如说界面各功能模块空间布局,控件位置选择,各功能模块区域的字体.背景颜色选择.添加位图,标题栏.菜单栏.状态栏等的重绘 ...

  2. rocketMq 消息偏移量 Offset

    消息偏移量 Offset queue0 offset 0   0-20  offset 4  20-40 纠错:每条消息的tag对应的HashCode. queue1 offset 1  0-20   ...

  3. JS中的offset scroll event client

    一.offset 一般用来检测盒子的偏移.位移,都是只读属性,不能赋值 offsetWidth和offsetHeight表示的是:调用者盒子的宽和高,包括盒子自身的padding和border off ...

  4. offset系列、client系列、scroll系列

      offset系列.client系列 <style> .testDOM { width: 200px; height: 200px; background-color: #2de; pa ...

  5. 元素偏移量 offset 系列

    offset 概述 offset翻译过来就是偏移量,我们使用offset系列相关属性可以动态的得到该元素的位置(偏移).大小等. 获得元素距离带有定位父元素的位置 获得元素自身的大小(宽度高度) 注意 ...

  6. jq获取元素偏移量offset()

    解释: 1 获取匹配元素在当前视口的相对偏移. 2 返回的对象包含两个整型属性:top 和 left demo1: 获取top与left var aaa = $(".aaa "); ...

  7. pwn之偏移量offset

    0x7fffffffdd00: 0x4141414141414141 0x4141414141414141 0x7fffffffdd10: 0x4141414141414141 0x414141414 ...

  8. 元素大小-偏移量(offset)客户区大小(client)滚动大小(scroll)

    一.偏移量---offset 1.定位父级 在理解偏移大小之前,首先要理解offsetParent.人们并没有把offsetParent翻译为偏移父级,而是翻译成定位父级,很大原因是offsetPar ...

  9. 深入理解客户区尺寸client

    前面的话 关于元素尺寸,一般地,有偏移大小offset.客户区大小client和滚动大小scroll.前文已经介绍过偏移属性,后文将介绍scroll滚动大小,本文主要介绍客户区大小client 客户区 ...

随机推荐

  1. 如何通过TortoiseGit(小乌龟)把本地项目上传到github上

    1.第一步: 安装git for windows(链接:https://gitforwindows.org/)一路next就好了, 如果遇到什么问题可以参考我另外一篇文章~^ - ^ 2.第二步:安装 ...

  2. Android 源代码结构

    简介 在使用Andriod SDK进行应用程序开发的时候,我们需要对源代码进行调试,有可能需要进入到某个Android API函数内部进行跟踪调试.但是,如果目标版本的SDK没有关联对应版本的源代码的 ...

  3. 涉及模式之 装饰器模式详解(与IO不解的情缘)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. LZ到目前已经写了九个设计模 ...

  4. Docker深入浅出系列教程——Docker初体验

    我是张飞洪,钻进浩瀚代码,十年有余,人不堪其累,吾不改其乐.我喜欢把玩代码,琢磨词句!代码算法让我穿透规律,文章摘句让我洞察人情.如果你觉得和我的看法不一样,请关注我的头条号,那我们一定合得来. Do ...

  5. 20162330 第十二周 蓝墨云班课 hash

    题目要求 利用除留余数法为下列关键字集合的存储设计hash函数,并画出分别用开放寻址法和拉链法解决冲突得到的空间存储状态(散列因子取0.75) 关键字集合:85,75,57,60,65,(你的8位学号 ...

  6. Socket程序从windows移植到linux下需要注意的

    )头文件 windows下winsock.h或winsock2.h linux下netinet/in.h(大部分都在这儿),unistd.h(close函数在这儿),sys/socket.h(在in. ...

  7. "一不小心就火了"团队采访

    团队采访 一. 采访团队 团队:一不小心就火了 采访形式:线上问答 二.采访内容 你们是怎么合理地具体分配组员里的工作的?有些团队会出现个别组员代码任务很重,个别组员无所事事的情况,你们有什么有效的方 ...

  8. 修改MYSQL的默认连接时长

    show global variables like 'wait_timeout'; 设置成10小时; set global wait_timeout=36000;

  9. JAVA_SE基础——38.单例设计模式

    本文继续介绍23种设计模式系列之单例模式. 我们在javaSE的基础学习中,会讲到:单例设计模式.模板设计模式.装饰者设计模式.观察者设计模式.工厂设计模式 我以后随着水平的提高,我会专门开个分类写设 ...

  10. gdb-peda调试总汇

    gdb-peda调试总汇 break *0x400100 (b main):在 0x400100 处下断点 tb一次性断点 info b:查看断点信息 delete [number]:删除断点 wat ...