offset

      offset 译为“偏移量”,是javascript很重要的一个概念。涉及到便宜量的主要有offsetLeft、offsetTop、offHeight、offsetWidth这四个属性还有一个偏移参照--定位父级offsetParent

      参照图:

    在理解偏移量之前,首先要理解offsetParent。从字面上来理解。应该是翻译为“偏移父级”,但并非如此,它被译为“定位父级”

      以下是对offsetParent的定义:

        与当前元素最近的经过定位(不是static)的父级元素。主要分为下列几种情况:

          1.元素自身有fixed定位,offsetParent的结果为null

          当元素自身有fixed固定定位时,我们知道固定定位的元素相对于窗口进行定位,此时没有定位父级,故offsetParent为null

          注意firefox浏览器有兼容问题

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="test" style="position: fixed"></div>
<script>
var test=document.getElementById('test');
console.log(test.offsetParent);
</script>
</body>
</html>

     在chrome中的执行结果:     

    在firefox的执行结果:

          2.当元素自身无fixed定位时,且父级元素都未经过定位,offParent的结果为<body>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="test"></div>
<script>
var test=document.getElementById('test');
console.log(test.offsetParent);
</script>
</body>
</html>

      效果如下:

        3.元素自身无fixed定位,且父级元素存在经过定位的元素,offsetParent的结果为离自身元素最近的经过定位的父级元素

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="box1" style="position: absolute;">
<div id="box2" style="position: absolute;">
<div id="test"></div>
</div>
</div>
<script>
var test=document.getElementById('test');
console.log(test.offsetParent);
</script>
</body>
</html>

      效果如下:

   偏移量

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

    offsetWidth

        offsetWidth表示元素在水平方向上占用的空间大小(包括边框和padding) 无单位(以px计)

          offsetWidth = border-left-width + padding-left + width + padding-right + border-right-width;

  

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#test{
border: 2px solid #000;
width: 200px;
height: 200px;
padding: 10px;
margin: 10px;
}
</style>
</head>
<body>
<div id="box1" style="position: absolute;">
<div id="box2" style="position: absolute;">
<div id="test"></div>
</div>
</div>
<script>
var test=document.getElementById('test');
console.log(test.offsetWidth);
</script>
</body>
</html>

  输出为:

    offsetHeight

      offsetHeight表示元素在垂直方向上占用的空间大小(包括边框和padding),无单位(以px计)

       offsetHeight = border-top-width + padding-top + height + padding-bottom + border-bottom-width

    [注意]如果存在垂直滚动条,offsetWidth也包括垂直滚动条的宽度;如果存在水平滚动条,offsetHeight也包括水平滚动条的高度

  

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="test" style="width:100px; height:100px; padding:10px; margin:10px; border:1px solid black; overflow: scroll;"></div>
<script>
//IE8-浏览器将垂直滚动条的宽度计算在width宽度和height高度中,width和height的值仍然是100px;
//而其他浏览器则把垂直滚动条的宽度从width宽度中移出,把水平滚动条的高度从height高度中移出,则滚动条宽度为17px,width宽度和height高度为剩下的83px if(window.getComputedStyle){
console.log(getComputedStyle(test).width,getComputedStyle(test).height)//83px
}else{
console.log(test.currentStyle.width,test.currentStyle.height);//100px
}
//122=1+10+100+10+1
console.log(test.offsetWidth,test.offsetHeight);
</script>
</body>
</html>

  

    chrome显示如下:

    offsetTop

      offsetTop表示元素的上外边框至offsetParent元素的上内边框之间的像素距离

    offsetLeft

      offsetLeft表示元素的左外边框至offsetParent元素的左内边框之间的像素距离

    注意事项:

        【1】所有偏移量属性都是只读的

        【2】如果给元素设置了display:none,则它的偏移量属性都为0

  

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="test" style="width:100px; height:100px; padding:10px; margin:10px; display: none;"></div>
<script> console.log(test.offsetWidth,test.offsetTop);
</script>
</body>
</html>

    chrome显示如下:

        【3】每次访问偏移量属性都需要重新计算

        

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="test" style="width:100px; height:100px; padding:10px; margin:10px; display: none;"></div>
<script>
console.time("time");
for(var i = 0; i < 100000; i++){
var a = test.offsetWidth;
}
console.timeEnd('time');//106.701ms
</script>
</body>
</html>

    chrome显示如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="test" style="width:100px; height:100px; padding:10px; margin:10px; display: none;"></div>
<script>
console.time("time");
var a = test.offsetWidth;
for(var i = 0; i < 100000; i++){
var b = a;
}
console.timeEnd('time');//6.274ms
</script>
</body>
</html>

  chrome显示如下:

  由上面代码对比可知,重复访问偏移量属性需要耗费大量的性能,所以要尽量避免重复访问这些属性。如果需要重复访问,则把它们的值保存在变量中,以提高性能

        OK   offset讲解暂告一段落!

    

详解offset的更多相关文章

  1. 图文详解Unity3D中Material的Tiling和Offset是怎么回事

    图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...

  2. JQ的offset().top与js的offsetTop区别详解

    一.前言 最近在做一个图片懒加载的插件,就纵轴(Y轴)而言,我需要时时获取图片的上偏移量,好判断是否已进入视图区域,而我所理解的是offsetTop应该是跟offset().top一样的,然后陷入了因 ...

  3. JQ的offset().top与JS的getBoundingClientRect区别详解,JS获取元素距离视窗顶部可变距离

     壹 ❀ 引 我在 JQ的offset().top与js的offsetTop区别详解 这篇博客中详细分析了JQ方法offset().top与JS属性offsetTop的区别,并得出了一条offset( ...

  4. js的client、scroll、offset详解与兼容性

    clientWidth:可视区宽说明:样式宽+padding参考:js的client详解 scrollTop : 滚动条滚动距离说明:chrome下他会以为滚动条是文档元素的,所以需要做兼容:var ...

  5. C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解

    前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 C#进阶系列——WebApi接口传参不再困惑:传参详解  ...

  6. Android图片缓存之Bitmap详解

    前言: 最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap.BitmapFactory这两个类. 图片缓存相关博客地址: Android图片缓 ...

  7. redis配置详解

    ##redis配置详解 # Redis configuration file example. # # Note that in order to read the configuration fil ...

  8. Linux C 字符串函数 sprintf()、snprintf() 详解

    一.sprintf() 函数详解 在将各种类 型的数据构造成字符串时,sprintf 的强大功能很少会让你失望. 由于 sprintf 跟 printf 在用法上几乎一样,只是打印的目的地不同而已,前 ...

  9. python之OS模块详解

    python之OS模块详解 ^_^,步入第二个模块世界----->OS 常见函数列表 os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows ...

随机推荐

  1. React:快速上手(6)——掌握React Router

    React:快速上手(6)——掌握React Router 引入Router 安装 npm install react-router-dom 基础组件 React Router中有三种类型的组件:路由 ...

  2. ISO8583

    最开始时,金融系统只有IBM这些大的公司来提供设备,象各种主机与终端等.在各个计算机设备之间,需要交换数据.我们知道数据是通过网络来传送的,而在网络上传送的数据都是基于0或1这样的二进制数据,如果没有 ...

  3. linux卸载mysql

    第二.停止MYSQL运行以及卸载老版本 service mysqld stop #暂停MYSQL yum remove mysql mysql-*  #卸载老版本MYSQL 通过上面的命令,我们先停止 ...

  4. KALI视频学习11-15

    KALI视频学习11-15 第十一集 看到openvas的主界面(web界面) ping靶机,看是否能正常连通 创建一个扫描目标Configuration-Targets,默认扫描目标为本机 添加一个 ...

  5. RedHat7.4最小化安装yum源不可用问题解决

    本次安装的RedHat7.4是安装在Oracle VM VirtualBox5.2.8虚拟机上面的,本文不对安装虚拟机步骤做详细说明. 工具准备: Oracle VM VirtualBox5.2.8 ...

  6. LeetCode——remove-duplicates-from-sorted-list-ii

    Question Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only dist ...

  7. C# Nginx平滑加权轮询算法

    代码很简单,但算法很经典,话不多说,直接上代码. public struct ServerConfig { /// <summary> /// 初始权重 /// </summary& ...

  8. 解题报告:hdu 1005 number subsequent

    2017-09-06 20:35:59 writer:pprp 本来以为这是一道水题,写了一个递归就赶紧交上去了, 结果超时了,看看数据范围100000000,肯定把栈给爆了 想用记忆化的方法,但是虽 ...

  9. SpringBoot创建定时任务

    之前总结过spring+quartz实现定时任务的整合http://www.cnblogs.com/gdpuzxs/p/6663725.html,而springboot创建定时任务则是相当简单. (1 ...

  10. Android -- 多线程下载, 断点下载

    1. 原理图 2. 示例代码 需要权限 <uses-permission android:name="android.permission.INTERNET"/> &l ...