<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>dOffsetLeft、dClientLeft、left区别</title>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<body style="position:relative;border:1px solid #ccc;margin:15px;padding:8px;">
<div id="tmpDiv" style="position:relative;margin:20px;padding:10px;border:1px solid #ccc;">
<div id="div" style="width:200px;height:100px;left:10px;top:10px;position:relative;border:1px solid #ccc;margin:25px;padding:10px;">
</div>
</div>
<script type="text/javascript">
var body = document.body;
console.log(body.scrollLeft);//横向滚动条左侧滚动的长度
console.log(body.scrollTop);//纵向滚动条顶部滚动的长度
var divObj = document.getElementById("div");
/*offsetLeft与offsetTop是以自身元素及自身元素的offsetParent相关的位移尺寸,先说一下offsetParent:
1、如果当前元素的祖先元素没有进行CSS定位(position为absolute或relative),offsetParent为body。
2、如果当前元素的祖先元素中有CSS定位(position为absolute或relative),offsetParent取最近的那个祖先元素。
*/
var offsetParent = divObj.offsetParent;
console.log(divObj.offsetParent);
/*
当前元素offsetLeft == 当前元素左边框到offsetParent元素左边框之间的距离(不包括此两者的边框尺寸)==
当前元素margin-left +
当前元素有效的left偏移量(需CSS定位设置position为absolute或relative) +
offsetParent元素的padding-left +
所有中间元素(如:tmpDiv)的margin-left值+padding-left值+border-left值
注意:如果当前元素的offsetParent为body时,并且body元素没有进行CSS定位,则offsetLeft包括body的margin-left,offsetTop包括body的margin-top;
如果body元素进行CSS定位或者offsetParent不是body,则不包括margin值;
如果offsetParent为body时,无论是否进行CSS定位,都包括body的border-left的值
*/
/*按照以下四种方式调整,分别查看offsetLeft和offsetTop的值:
1、当去掉id='tmpDiv'的div,同时去掉body元素的CSS的position定位;
2、当去掉id='tmpDiv'的div,但包括body元素的CSS的position定位;
3、包括中间元素,同时body元素进行CSS定位;
4、将id="tmpDiv"进行CSS的position定位;
*/
var dOffsetLeft = divObj.offsetLeft;
var dOffsetTop = divObj.offsetTop;
//jQuery方式
/*规则与offsetLeft规则基本一致,只是:
1、不包括当前元素的margin-left值,
2、当offsetParent为body时,并且body进行了CSS定位,则不包括border-left的值
*/
var $position = $(divObj).position();
console.log("$left:"+$position.left+",$top:"+$position.top);
//当前元素相对父元素(非祖先元素)的偏移,当前元素需要进行CSS的position定位,默认情况和position为static的情况失效,与offsetParent无关
//当前元素的margin-left外边缘与父元素padding-left内边缘之间的距离
var dLeft = divObj.style.left;
//当前元素的margin-top外边缘与父元素padding-top内边缘之间的距离
var dTop = divObj.style.top;
/*
注意:offsetLeft(offsetTop)与style.left(style.top)的区别
1. style.left 返回的是字符串,如28px,offsetLeft返回的是数值28,如果需要对取得的值进行计算,用offsetLeft比较方便;如果拿到offsetLeft设置style.left的值,需加'px'。
2. style.left是读写的,offsetLeft是只读不能写的,要改变div的位置,只能修改style.left。
3. style.left的值需要事先定义,否则取到的值为空。而且必须要定义在html里,如果定义在css里,style.left的值仍然为空,但元素偏移有效;而offsetLeft则仍能取到。
*/
//返回内边距的边缘和边框的外边缘之间的水平和垂直距离,即左、上边框的宽度,与offsetParent无关
var dClientLeft = divObj.clientLeft;
var dClientTop = divObj.clientTop;
console.log("dOffsetLeft:"+dOffsetLeft+",dOffsetTop:"+dOffsetTop+",dClientLeft:"+dClientLeft+",dClientTop:"+dClientTop+",dLeft:"+dLeft+",dTop:"+dTop);
//jQuery方法
//获取匹配元素在当前视口的相对偏移,即当前元素左边框/上边框(不包括边框)到浏览器左边缘/上边缘的距离
//包括:当前元素的margin-left + 当前元素有效left值 + 所有祖先元素的pading-left值+border-left值+margin-left值,一直到浏览器左边缘
var $offset = $(divObj).offset();
console.log("$left:"+$offset.left+",$top:"+$offset.top);
/*
总结:
1、通过jQuery的offset()获取当前元素到浏览器边缘尺寸,并可以使用offset({ top: 10, left: 30 })设置尺寸
2、通过jQuery的position()或DOM对象的offsetLeft/offsetTop获取当前元素到offsetParent元素的尺寸(如:子元素左边框到父元素左边框之间的距离)
3、通过DOM对象的style.left/style.top获取/设置当前元素的偏移量
*/
</script>
</body>
</html>