详解offset

  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讲解暂告一段落!

 

 

 

 

 

    

posted @ 2017-05-08 10:33  游鱼与渔  阅读(2451)  评论(0编辑  收藏  举报