JS中DOM盒子模型深入剖析之操作盒子的样式

作者:日期:2017-11-23 16:15:23 点击:149

CSS盒子模型

Alt text

JS盒子模型

提供一些属性和方法用来描述当前盒子的样式的

clientWidth / clientHeight

当前盒子可视区域的宽度和高度
可视区域:内容宽高+padding
clientWidth = width + padding(Left/Right)
clientHeight = height + padding(Top/Bottom)

和内容是否溢出以及我们是否设置了 overflow:hidden; 没有关系

//=>获取当前页面一屏幕的宽度(加或者是为了兼容所有的浏览器)
document.documentElement.clientWidth || document.body.clientWidth
 
//=>获取当前页面一屏幕的高度
document.documentElement.clientHeight || document.body.clientHeight

面试题:让一个盒子在整个页面水平和垂直都居中的位置? 如果不知道盒子的宽度和高度如何处理?

css

//=>使用定位:需要知道盒子的具体宽高
.box {
position: absolute;
top: 50%;
left: 50%;
margin: -50px 0 0 -100px;
width: 200px;
height: 100px;
background: red;
}
 
//=>使用定位:不需要知道盒子的具体宽高(不兼容IE低版本浏览器)
.box {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 200px;
height: 100px;
background: red;
}
 
//=>使用CSS3flex伸缩盒模型(不兼容)
html {
height: 100%;
}
 
body {
display: flex;
height: 100%;
flex-flow: row wrap;
align-items: center;
justify-content: center;
}
 
.box {
width: 200px;
height: 100px;
background: red;
}

JS

//=>JS中只要获取到当前盒子具体的LEFT/TOP值即可
//=>一屏幕的宽高-盒子的宽高,最后除以2,获取的值就是它应该具备的LEFT/TOP(这个值可以让他处于页面中间)
var winW = document.documentElement.clientWidth || document.body.clientWidth;
var winH = document.documentElement.clientHeight || document.body.clientHeight;
var boxW = box.clientWidth;
var boxH = box.clientHeight;
box.style.left = (winW - boxW) / 2 + 'px';
box.style.top = (winH - boxH) / 2 + 'px';

clientTop 和 clientLeft

只有top和left,没有right和bottom这两个属性
clientTop:盒子上边框的高度
clientLeft:左边框的宽度
获取的结果其实就是border-width值

通过JS盒子模型属性获取的结果是不带单位的,而且只能是整数(它会自动四舍五入)

.box{
border:10.8px silid red;
}
 
box.clientLeft =>11

offsetWidth 和 offsetHeight

在clientWidth和clientHeight的基础上加上盒子的边框即可

和内容是否溢出没关系

真实项目中如果想获取一个盒子的宽度和高度,我们一般用offsetWidth(而不是clientWidth),border也算是当前盒子的一部分

scrollWidth 和 scrollHeight

[ 没有内容溢出 ]
获取的结果和clientWidth/clientHeight是一样的

[ 有内容溢出 ]
真实内容的宽度或者高度(包含溢出的内容),在加上左padding或者上padding的值

有内容溢出的情况下,我们通过scrollWidth或者scrollHeight获取的结果是一个约等于的值
1) 有内容溢出,每个浏览器由于对行高或者文字的渲染不一样,回去的结果也是不一样的
2) 是否设置 overflow:hidden 对最后获取的结果也有影响

//=>获取当前页面真实高度(包含溢出内容)
document.documentElement.scrollHeight||document.body.scrollHeight

在JS中获取元素具体的样式值

通过JS盒子模型属性获取的结果都是盒子的组合样式值,不能直接获取某一个具体样式值,例如:我就想获取左padding…

curEle.style.xxx

获取当前元素所有写在行内样式上的样式值

特殊:只有把样式写在行内样式上,才可以通过这种办法获取到(写在其它地方的样式是获取不到的)

这种办法在真实项目中使用的特别少:因为我们不可能把所有元素的样式都写在行内上(这样要内嵌和外联式就没用了)

window.getComputedStyle / currentStyle

只要当前元素在页面中显示出来了,我们就可以获取其样式值(不管写在行内还是样式表中);也就是获取所有经过浏览器计算过的样式(当前元素只要能在页面中展示,那么它的所有样式都是经过浏览器计算的,包含一些你没有设置,浏览器按照默认样式渲染的样式)

window.getComputedStyle:适用于标准浏览器,但是在IE6~8中就不兼容了,IE6~8下我们使用 curEle.currentStyle来获取需要的样式值

//=>通过getComputedStyle获取的结果是一个对象,对象中包含了所有被浏览器计算过的样式属性及属性值
// window.getComputedStyle([当前需要操作的元素],[当前元素的伪类,一般写null])
// window.getComputedStyle(box,null)['paddingLeft'] 这种方式可以在获取的对象中找到某一个具体样式属性的值(通过.paddingLeft也可以)
 
//=>在IE6~8浏览器的window全局对象中,没有提供getComputedStyle这个属性方法,我们只能使用currentStyle属性获取元素的样式
// [当前元素].currentStyle 获取的结果也是一个包含当前元素所有的样式属性和值的对象
// box.currentStyle.paddingLeft

以后再想获取元素的样式,我们需要写两套,这样的话,我们可以把获取样式的操作封装成为一个公共的方法:getCss

/*
* getCss:获取当前元数某一个样式属性值
* @parameter
* curEle:当前需要操作的元素
* attr:当前需要获取的样式属性名
* @return
* 获取的样式属性值
*/
function getCss(curEle,attr){
var value=null;
if('getComputedStyle' in window){
value = window.getComputedStyle(curEle,null)[attr];
}else{
value = curEle.currentStyle[attr];
}
return value;
}

对getCss进行优化
1、去除获取值的单位
2、获取透明度的兼容

function getCss(curEle, attr) {
var value = null;
if ('getComputedStyle' in window) {
value = window.getComputedStyle(curEle, null)[attr];
} else {
if (attr === 'opacity') {
value = curEle.currentStyle['filter'];
var reg = /^alpha\(opacity=(.+)\)$/;
reg.test(value) ? value = reg.exec(value)[1] / 100 : value = 1;
} else {
value = curEle.currentStyle[attr];
}
}
var temp = parseFloat(value);
!isNaN(temp) ? value = temp : null;
return value;
}

上一篇: 珠峰培训前端JS基础知识学习大纲

下一篇: JQ源码解读和插件封装