前言:先看下w3c与之相关的介绍:

element.offsetHeight 返回元素的高度。
element.offsetWidth 返回元素的宽度。
element.offsetLeft 返回元素的水平偏移位置。
element.offsetParent 返回元素的偏移容器。
element.offsetTop 返回元素的垂直偏移位置。

1,简单来说就是偏移量,但它的参考对象到底是谁,我们慢慢来看.

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
<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>
<body>

<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>

效果如下:

offsetLeft 解析 随笔 第1张

这个demo中可以看出在默认情况下每个box的偏移值都是以浏览器为参考对象的.

 

2.如果我们给父级加上定位呢?(box1添加相对定位)

<body>
<style> body { margin:0;  } .box1 { width:300px; height:300px; margin:100px; background:#333; overflow:hidden; position:relative;} //box1设置相对定位 .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>

效果:

offsetLeft 解析 随笔 第2张

所以给父级添加定位之后,offset的偏移值就会变成相对于父级的偏移值.(除了position:static;外的所有定位,如fixed,relative,absolute都会使偏移值的参考对象变为父级))

 

 3.在我们给父级添加定位之后,还想获取元素相对于浏览器窗口的偏移值怎么办?

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

  这就需要封装一个函数(用到了offsetParent :获取上一级定位元素对象):

function offset(obj,direction){        //传入对象 和 方向
    //将top,left首字母大写,并拼接成offsetTop,offsetLeft
    var 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; }

实际运用是这样的:

<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>

<body>
<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,offsetLeft
        var 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>

 

运用到移动端拖拽事件(jquery):

 // 拖拽事件
  var x1; var x2; var x_c;  //指针划过的距离 var xoffsetLeft;
$(
'#ulListMoble').on('touchstart', function (e) { var touch = e.originalEvent.targetTouches[0]; x1 = touch.pageX; }); $('#ulListMoble').on('touchmove', function (e) { var touch = e.originalEvent.targetTouches[0]; xoffsetLeft = $('#ulListMoble')[0].offsetLeft; x2 = touch.pageX; x_c = x1 - x2; xoffsetLeft -= x_c; // console.log(xoffsetLeft); if (xoffsetLeft < 0) { $('#ulListMoble').css({ "left": xoffsetLeft + "px" }) } x1 = x2; }); })

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄