以一个例子来区别这几个属性的计算方式:
父元素为橘黄色区域,子元素为蓝色边框包裹的区域。
父元素布局:
子元素布局:(content设置width、height都为100px,因为右侧出现滚动条,所以浏览器布局显示content width 90.4为去掉滚动条的宽度。)
offset 类
offsetWidth
:返回一个元素的布局宽度,不包括溢出部分,即 offsetwidth = content width + padding*2 + border *2
(offsetHeight 同理)
所以上例中子元素获取 offsetWidth :120 = 100 +5*2+5*2
offsetLeft
:获取元素距离最近的(非static
定位)父元素的距离,即以父元素为基准,左上角为原点,子元素的x
轴坐标。(offsetTop 同理),如果没有定位则为距离根元素(在标准兼容模式下为html元素;在怪异呈现模式下为body元素)顶部的距离。
所以上面例子中,子元素offsetLeft 即相对于父元素的 x 轴的偏移量 20px。如果没有定位就是相对于body 的左侧的距离。
client 类
clientWidth
:元素的内部宽度,以像素计。该属性包括内边距 padding,但不包括边框 border、外边距 margin 和垂直滚动条(如果有的话)。返回值为四舍五入的整数。
内联元素以及没有 CSS 样式的元素的 clientWidth 属性值为 0。
所以上例中子元素的 clientWidth
值为 100px =90.4+padding (5*2);
如果内容没有溢出无滚动条 :clientWidth
值为110px = 100px+5*2
clientLeft
返回的是元素左边框的宽度。
srcoll 类
scrollHeight:
获取元素内容区域的实际高度,包括 padding
。
子元素中包含7个 p 元素,p元素 height:21px,margin 16px。
注意: p 元素垂直margin 会重叠,所以 7 个 p 元素,共计算8 个margin值,与BFC 有关。
所以上例中 子元素的 scrollHeight 值为 285px=21*7 + 16*8 +5*2(padding)
scrollTop
:可以获取或设置一个元素的内容垂直滚动的像素数。
一个元素的 scrollTop 值是这个元素的内容顶部(卷起来的)到它的视口可见内容(的顶部)的距离的度量。当一个元素的内容没有产生垂直方向的滚动条,那么它的 scrollTop 值为0。
mouse.event 类 clinetY、offsetY、pageY等
参考MDN:鼠标事件
- clinetY:返回当事件被触发时鼠标指针向对于浏览器页面(客户区)的垂直坐标。 客户区指的是当前窗口。
- offsetY:事件对象与目标节点的内填充边(padding edge)在 Y 轴方向上的偏移量。
- pageY:鼠标指针相对于整个文档的Y坐标。返回触发事件的位置相对于整个 document 的 Y 坐标值。由于其参考物是整个 dom,所以这个值受页面垂直方向的滚动影响。例如:当你垂直方向向下滚动了 50 pixel,那么你在顶端进行点击的时候,获取的pageY为 50pixed 而不是 0。
测试例子代码:
<style>
html,body{
border:0;
padding: 0;
margin: 0;
}
.fel{
position: relative;
width: 200px;
height: 200px;
margin: 10px;
background-color: #ff7117;
}
.sel{
position: absolute;
top: 20px;
left: 20px;
padding: 5px;
border: 5px solid #00bcd4;
width:100px;
height: 100px;
background-color: #abff6b;
text-align: center;
overflow: auto;
}
</style>
<div class="fel">
<div class="sel">
<p>第1行</p>
<p>第2行</p>
<p>第3行</p>
<p>第4行</p>
<p>第5行</p>
<p>第6行</p>
<p>第7行</p>
</div>
</div>
<script>
var sel=document.querySelector(".sel")
console.log('sel.offsetWidth:'+sel.offsetWidth)// 120
console.log('sel.offsetLeft:'+sel.offsetLeft);//20
console.log('sel.offsetParent:',sel.offsetParent);//div.fel
console.log('sel.clientWidth:'+sel.clientWidth);//100
console.log('sel.clientLeft:'+sel.clientLeft);//5
console.log('sel.scrollWidth:'+sel.scrollWidth);//100
console.log('sel.scrollHeight:'+sel.scrollHeight);//285
console.log('sel.scrollTop:'+sel.scrollTop);//0
sel.addEventListener('mousedown',function (e) {
console.log('e.clientY:'+e.clientY)
console.log('e.offsetY:'+e.offsetY)
console.log('e.pageY:'+e.pageY)
},false)
sel.addEventListener('mouseup',function (e) {
console.log('子元素sel.scrollTop:'+sel.scrollTop)
},false)
</script>