offset、scroll还有client这三个属性总是让人头疼,好不容易记下没过多久就又忘了。。。这次好好总结一下(@_@;)~
为了让文章更显而易见一点,我们先定义段代码:
<div class="box">
<div class="box1"></div>
</div>
<div class="box2"></div>
如上所示,我们有三个盒子。
然后再来定义样式:
.box {
width: 300px;
height: 300px;
margin: 0 auto;
padding: 50px 100px;
background-color: orange;
position: relative;
}
.box1 {
width: 100px;
height: 100px;
border: 10px solid transparent;
background-color: green;
}
.box2 {
width: 100px;
height: 100px;
background-color: blue;
position: absolute;
left: 250px;
top: 200px;
}
这样,我们就可以得到如下的页面:
其中橙色的box是最外一层的大盒子,包含着绿色的box1,蓝色的box2和box在同一级。
好了,有了上面这个简单(丑陋)的页面,我们就可以好好的来研究一下了~
offset系列
打印出上面每个盒子对应offset系列的属性值:
由上图我们可以看出,offsetWidth返回的是元素包含padding和border的宽度,offsetHeight一样,只不过返回的是高度而已,但offsetLeft和offsetTap返回的值不太明显,但其实仔细看,会发现他们返回的都是相对于offsetParent元素的值,当offsetParent为body时,返回相对body的距离,offsetParent为box时,返回相对于box的距离。
我们来查看一下offset系列属性的定义:
- offsetWidth: 只读属性,返回一个元素的布局宽度,包括边框(border)、内边距(padding)、内容(content)和竖直滚动条的宽度(如果有的话)。
- offsetHeight:只读属性,返回一个元素的像素高度,包括边框(border)、内边距(padding)、内容(content)和竖直滚动条的宽度(如果有的话)。
- offsetLeft:只读属性,返回元素相对于offsetParent元素的左边界对应的像素值。
- offsetTop: 只读属性,返回元素相对于offsetParent元素的顶部距离。
- offsetParent:只读属性,返回一个指向最近的包含该元素的定位元素。
这样就很清楚了,不过怎么知道offsetWidth会包含滚动条的宽度?
其实很简单,在box的样式里加一行代码:
.box {
overflow: hidden;
}
这样就好了,最后打印的结果并没有变化。
对了, 还有offsetParent属性,如果没有定位的父元素怎么办呢?
由上面的例子可以看出,如果没有定位的父元素,则默认是body元素。
其实按照MDN的说法,如果没有定位的父元素,则offsetParent为最近的table、table-cell或根元素(body元素)。
最后,要注意的是:
offsetTop和offsetLeft在计算时不考虑父元素的边框
scroll系列
我们还是先打印出scroll系列属性的值来看看~
\
乍一看好像和offset没啥区别。。。不过仔细看看,会发现scrollWidth和scrollHeight不会计算元素的边框(border)。
但是scrollTop和scrollLeft一直是0是什么鬼呢( ఠൠఠ )ノ?
想不出原因的话,我们让元素滚动一下试试~(毕竟scroll,scroll,一直在叫我们滚嘛。。。( ╯□╰ )囧)
给之前的样式表添加如下样式:
.box {
overflow: scroll;
}
.box1 {
height: 1000px;
}
就是给box加了个滚动条,把box1的高度改为了1000px。
现在我们的图就是这样了:
为了看清楚scrollTop的值,为box元素添加事件监听器,让box在滚动的时候打印一下scrollTop~
box.addEventListener("scroll", function(e) {
console.log("scrollTop", this.scrollTop);
});
可以得到如下的结果:
当我从上向下移动滚动条的时候,scrollTop的值在逐渐增大。
这下明白了,原来scrollTop获得的是元素滚动的距离。换句话说,也就也是竖直滚动条到元素顶部的距离。
scrollLeft类似,就不再说了。
做个小总结:
- scrollWidth: 只读属性。一个元素内容宽度的度量,包括由于溢出导致的视图中不可见内容(不包括滚动条和border)。
- scrollHeight: 只读属性。一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容(不包括滚动条和border)。
- scrollTop: 读取元素滚动条到元素顶部的距离(不包括滚动条和border)
- scrollLeft: 读取元素滚动条到元素左边的距离(不包括滚动条和border)
这里补充一下:
offset系列属性是包含滚动条的。
client系列
直接看结果:
可以看到,clientHeight和clientWidth和offset差不多,只不过不包含边框的值(也不包含滚动条)。
而clientTop和clientLeft则返回了元素的边框宽度。
MDN的描述如下:
- clientHeight: 只读属性,对于没有定义CSS或者内联布局盒子的元素为0,同时它是元素内部的高度(单位像素),包含内边距,但不包括水平滚动条、边框和外边距。
- clientWidth: 元素的内部宽度,以像素计。该属性包括内边距,但不包括垂直滚动条(如果有)、边框和外边距。
- clientTop: 只读元素,一个元素顶部边框的宽度(以像素表示)。不包括顶部外边距或内边距。
- clientLeft: 表示一个元素的左边框的宽度,以像素表示。
要注意的是:
如果元素的文本方向是从右向左(RTL, right-to-left),并且由于内容溢出导致左边出现了一个垂直滚动条,则该属性包括滚动条的宽度。
最后,我们拓展一点内容
-
关于event事件的几个属性
- clientX和clientY: 相对于浏览器(可视区左上角0,0)的坐标,不包含滚动区域。
- screenX和screenY: 相对于设备屏幕左上角(0,0)的坐标。
- offsetX和offsetY: 相对于事件源左上角(0,0)的坐标,不包括border。
- pageX和pageY: 相对于整个网页左上角(0,0)的坐标,包含滚动区域。
-
window相关宽高属性
- window.outerHeight:获取整个浏览器窗口的高度(单位:像素),包括侧边栏(如果存在)、窗口镶边(window chrome)和窗口调正边框。包含调试窗及浏览器边框
- window.outerWidtht:表示整个浏览器窗口的宽度,包括侧边栏(如果存在)、窗口镶边(window chrome)和调正窗口大小的边框。包含调试窗及浏览器边框
- window.innerHeight:浏览器窗口的视口(viewport)高度(以像素为单位),如果存在水平滚动条,则包括它。不包含调试窗及浏览器边框
- window.innerWidth:浏览器视口(viewport)宽度(单位:像素),如果存在垂直滚动条则包括它。不包含调试窗及浏览器边框
- window.screen.width:声明了显示当前浏览器的屏幕的宽度,以像素计
- *window.screen.height:声明了显示当前浏览器的屏幕的高度,以像素计
- *window.screen.availHeight:声明了显示浏览器的屏幕的可用高度,以像素计。除去我们底部任务栏外的屏幕高度
- *window.screen.availWidth:声明了显示浏览器的屏幕的可用宽度,以像素计
- *window.screenLeft:只读属性,返回窗口的左上角在屏幕上的x坐标。在Firefox等浏览器中使用的是screenX属性。
- *window.screenTop:只读属性,返回窗口的左上角在屏幕上的y坐标。在Firefox等浏览器中使用的是screenY属性。