很长一段时间对页面的各种尺寸一直迷迷糊糊,客户区尺寸、偏移尺寸、滚动尺寸、屏幕尺寸,各种尺寸各种定位都有差别,下面我们就通过几个实例来分析一下它们分别是什么含义,以及不同css设置对它们产生的影响。
0 前言
body引用:
document.body
document.getElementsByTagName('body')[0] (兼容性写法)
html引用:
document.documentElement
页面结构
<head>
...
<style>
body{
position: relative;
}
#el{
position: absolute;
top: 50px;
left: 50px;
margin: 30px;
padding: 5px;
width: 200px;
height: 200px;
background: #c55;
border: 10px solid #55c;
overflow: auto;
}
</style>
</head>
<body>
<div id="el">
<div id="el-text"></div>
</div>
</body>
实例一:无滚动条
设定元素尺寸小于el
#el-text{
width: 150px;
height: 150px;
}
我们针对元素el获取它的各种尺寸值,测试如下:
var el = document.getElementById("el");
console.log("client", el.clientWidth); //210
console.log("client", el.clientHeight); //210
console.log("client", el.clientTop); //10
console.log("client", el.clientLeft); //10
console.log("offset", el.offsetWidth); //230
console.log("offset", el.offsetHeight); //230
console.log("offset", el.offsetTop); //80
console.log("offset", el.offsetLeft); //80
console.log("scroll", el.scrollWidth); //210
console.log("scroll", el.scrollHeight); //210
console.log("scroll", el.scrollTop); //0
console.log("scroll", el.scrollLeft); //0
然后接下来我们来分析一下各种尺寸的含义
1、客户区尺寸:
clientWidth/clientHeight
—— 元素的内容区域,不包含外层定位和border,大小=content+padding*2
clientTop/clientLeft
—— 客户区到元素上/左边界(可视区域)的距离,大小=border
2、偏移尺寸:
offsetWidth/offsetHeight
—— 元素的可视区域,不包含外层定位,大小=content+padding*2+border*2
offsetTop/offsetLeft
—— 客户区定位尺寸,大小=top/left+margin
3、滚动尺寸:
scrollWidth/scrollHeight
—— 元素的可视区域+滚动区,不包含外层定位和border,大小=content(包括被滚动条隐藏的部分)+padding*2,如果不存在滚动条则和客户区尺寸相同
scrollTop/scrollLeft
—— 滚动区定位尺寸,大小=滚动隐藏的大小
实例二:有滚动条
我们在修改容器el-text
的大小,使元素部分隐藏,出现滚动条
#el-text{
width: 250px;
height: 250px;
}
为了更方便测试我们加入事件监听,以查看滚动条变化
var el = document.getElementById("el");
console.log("client",el.clientWidth); //193
console.log("client",el.clientHeight); //193
console.log("client",el.clientTop); //10
console.log("client",el.clientLeft); //10
console.log("offset",el.offsetWidth); //230
console.log("offset",el.offsetHeight); //230
console.log("offset",el.offsetTop); //80
console.log("offset",el.offsetLeft); //80
document.addEventListener('mouseup', function(){
console.log("scroll",el.scrollWidth); //255
console.log("scroll",el.scrollHeight); //255
console.log("scroll",el.scrollTop); //62
console.log("scroll",el.scrollLeft); //62
});
1、由数据我们可以看到,clientWidth/clientHeight
发生了变化,因为可视区发生了改变,滚动条的出现压缩了可视区空间,将其由210->193,那这减少的17是不是就是滚动条的宽度呢?
我们用Page Ruler插件进行测量(注意貌似Ruler工具不支持file://路径的测量,所以我们可以用webstorm创建本地服务器进行测试),得到如图结果
发现正好是17px,所以得出结论:clientWidth/clientHeight
只指示可视区大小
2、clientTop/clientLeft
,offsetWidth/offsetHeight
,offsetTop/offsetLeft
都没发生改变,因为元素边框、整体大小都没改变
3、scrollWidth/scrollHeight
:210->255,scrollHeight
:210->255,也符合大小=可视区+隐藏宽高
滚动到最底部
firefox环境,chrome环境下测试结果是
scrollWidth
:210->255,scrollHeight
:210->260,不知道为什么会有这么诡异的数值,如果有朋友知道还请指点一下
包括firefox下也有不符合逻辑的部分,有的属性会出现1px的偏差,通常发生在offsetWidth/offsetHeight
scrollTop
:0->62,scrollLeft
:0->62,符合大小=5(padding)+250(子元素大小)-193(可视区大小),也就是滚动条距元素边界(不包括border)的距离
firefox环境,chrome环境任然表现诡异
scrollTop
:0->67.19999694824219,scrollLeft
:0->61.599998474121094
实例三:border-box
下面我们再来修改盒子box-sizing属性,我们想单独分析box-sizing带来的影响,所以将元素状态改回到实例一状态
#el{
box-sizing: border-box;
}
#el-text{
width: 150px;
height: 150px;
}
我们发现图形整体都缩小了,输出结果
console.log("client",el.clientWidth); //180
console.log("client",el.clientHeight); //180
console.log("client",el.clientTop); //10
console.log("client",el.clientLeft); //10
console.log("offset",el.offsetWidth); //200
console.log("offset",el.offsetHeight); //200
console.log("offset",el.offsetTop); //80
console.log("offset",el.offsetLeft); //80
console.log("scroll",el.scrollWidth); //180
console.log("scroll",el.scrollHeight); //180
console.log("scroll",el.scrollTop); //0
console.log("scroll",el.scrollLeft); //0
1、clientWidth/clientHeight
发生了变化,由box-sizing: border-box;
的定义我们可以分析出来,180=200-10*2,也就是说我们的width设置会包括border的值,所以可视区也就缩小为180
2、clientTop/clientLeft
,offsetTop/offsetLeft
没有变化,因为虽然border计入width范围,但不影响它的值和元素的相对定位
3、offsetWidth/offsetHeight
:230->210,原因和1相同,210=180+5*2+10*2
4、scrollWidth/scrollHeight
:210->180,原因和1相同
如描述有偏差欢迎指出~