| ✍️ Tangxt | ⏳ 2020-06-29 | 🏷️ DOM 操作 |
看看JS盒子模型属性都是些啥值?
clientWidth & clientHeight
具体点:
.box {
width: 300px;
height: 300px;
padding: 20px;
border: 10px solid yellow;
margin: 20px auto;
line-height: 32px;
}

clientWidth = 300 + 20 * 2 = 340
clientHeight = 300 + 20 * 2 = 340
如果盒子模型是 border-box ,如:
.box {
box-sizing: border-box;
width: 300px;
height: 300px;
padding: 20px;
border: 10px solid yellow;
margin: 20px auto;
line-height: 32px;
}
那么:
clientWidth = 300 - 10 * 2 = 280
clientHeight = 300 - 10 * 2 = 280
所以,都是看盒子可视区域的宽高!即求出「padding+content」的值!
总共有13个,其中 offset 有个 parent ,它获取的是某个元素,即它不是具体的数值!
所以凡是: xxxWidth 、 xxxHeight 、 xxxTop 、 xxxLeft 这样的值,都是咩有单位滴!


为啥 clientWidth 就不是 341 呢?
难道这是随缘的?不过我们一般写CSS都不会出现这样的浮点数值 300.5px 吧……
我们可以获取一个盒子的可视区域的宽高,那么一个页面的可视区域的宽高我们能否获取呢?
我们知道一个页面内容特别多的时候,就会出现滚动条,如你打开 https://www.bilibili.com/,可以看到页面右侧有个滚动条
我们想要获取页面一屏幕的宽高,所谓的一屏幕,就是你不滚动滚动条,所看到的结果,你滚动了滚动条,就相当于是在查看溢出的内容! -> 这是站在「一屏幕」这个度量来看的,如果页面内容很多,即页面行长,那么就可以说成是「有几个屏的长度」……
总之,超出一屏幕的内容,就是溢出的内容! -> 滚动滚动条就是在查看溢出的内容
那么我们如何获取「一屏幕」的宽高呢?
有两种姿势:
所以可有:
let winW = document.documentElement.clientWidth || document.body.clientWidth;
let winH = document.documentElement.clientHeight || document.body.clientHeight;
document.documentElement.clientWidth 在低版本浏览器不支持,所以用 document.body.clientWidth 作为兜底值!
我们获取一屏幕的宽高的本质是,获取 html 元素,或 body 元素的可视化区域的宽高!
Q:垂直滚动条的出现算不算可视化区域的宽?

如果是 border-box :

削掉滚动条的宽+border的宽……
需求:
我们想要让一个盒子在整个页面里边绝对居中(水平和垂直都居中)
盒子目前是这样的:
body {
margin: 0;
padding: 0;
}
.box {
box-sizing: border-box;
width: 300px;
height: 300px;
padding: 20px;
border: 10px solid yellow;
line-height: 32px;
overflow: auto;
}
<div class="box" id="box">
1.你日渐平庸,甘于平庸,将继续平庸。—— 《以自己喜欢的方式过一生》
2.我将融入剧烈争斗的大人世界,要在那边孤军奋战,必须变得比任何人都坚不可摧。——《海边的卡夫卡》
</div>
姿势1:
.box {
position: absolute;
top: 50%;
left: 50%;
margin-left: -150px;
margin-top: -150px;
}
不好之处:我们必须知道盒子的固定宽高,不然,你如何确定 margin-left/top 的值?
姿势2:
基于CSS3变形属性中的位移,在不知道宽高的情况下也能实现效果
.box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
基于盒子自身位移一半!
姿势3:
这种姿势的兼容性不是特比好
.box {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
}
姿势4:
html,
body {
height: 100%;
}
body {
display: flex;
/* 主轴对齐姿势 */
justify-content: center;
/* 交叉轴对齐姿势 */
align-items: center;
}
flex容器,即 body 元素,得撑满整个屏幕的高度!
所以还有一种简单姿势:
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex布局这种姿势很简单,所以现在在项目里边一般都用这个来让盒子绝对居中!
思路:

在日常生活中,你也可以用这种姿势来居中一个东西,如你面前有个键盘,你手上拿着手机,那么你如何才能让手机居中与键盘呢? -> 如果你的笔记本是被个支架支起来的,那么如果你居中了手机,同样,支架也可以对称起来!
做法:
// JS实现居中:(一屏幕的宽度-盒子的宽度)/2 === LEFT
let winW = document.documentElement.clientWidth,
winH = document.documentElement.clientHeight,
box = document.getElementById("box");
box.style.position = "absolute";
box.style.left = (winW - 300) / 2 + "px";
box.style.top = (winH - 300) / 2 + "px";
性能咩有CSS那么好,但是很方便!不过,如果屏幕变化了,这居中就GG了,因为我们这JS只执行一次!
所以,我简单封装了一下:
function boxCenter(parent, sonId) {
// JS实现居中:(一屏幕的宽度-盒子的宽度)/2 === LEFT
let winW = parent.clientWidth,
winH = parent.clientHeight,
box = document.getElementById(sonId);
box.style.position = "absolute";
box.style.left = (winW - 300) / 2 + "px";
box.style.top = (winH - 300) / 2 + "px";
}
boxCenter(document.documentElement, "box");
window.onresize = function() {
boxCenter(document.documentElement, "box");
};
// border-left-width
box.clientLeft
// border-top-width
box.clientTop
只能获取左和上的大小,而右和下的是无法获取的,因为咩有 clientRight 、 clientBottom 这样的属性……
鼠标距离可视区域左上角的距离(用于事件)
box.onclick = function(e) {
console.log(e.clientX);
console.log(e.clientY);
};

➹:js盒子模型常用属性_sushans的博客-CSDN博客_js盒子模型
➹:JS-盒子模型_繁花落幕的博客-CSDN博客_js中盒子模型的组成部分
clientWidth 和 clientHeight ,是某个盒子的 content+padding 的结果(不同的盒子模型,对应的计算过程是不一致的),注意「滚动条」不是 client 的一部分,而且点击滚动条不会触发click事件,但点击 border 则会触发click事件!滚动条会削掉 content 的大小,一个滚动条的大小是 17*17 ,假如一个盒子大小是 1366*768 ,那么 clientX/Y 就是 1349*768 -> 只有垂直滚动条才会削去盒子 content 的 width -> 削去 17px ,而水平滚动条则不会!
<style>
body {
margin: 0;
padding: 0;
height: 768px;
width: 100%;
border: 20px solid yellow;
}
</style>
</head>
<body>
我是body
</body>