JS基础(八)盒子模型

JS中DOM盒子模型深入分析

CSS盒子模型

传统盒子模型

width height:不是盒子的宽高,而是盒子中的内容

盒子的宽度=width+border2+padding2//在一个对称的模型中

CSS3新增加的盒子模型

增加该属性,width和height的数值就是盒子的宽高;

1
box-sizing:border-box;

JS盒子模型

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

client

clientWidth / clientHeight

当前盒子可视区域的宽度和高度
可视区域:内容的宽高+padding*2
clientHeight=height+padding(top&&bottom)
clientWidth=height+padding(left&&right)
和内容是否溢出和我们是否设置了overflow:hidden没有关系

1
document.documentElement.clientWidth||document.body.clientHight

//获取当前页面一屏幕的宽度

在不知盒子宽高的情况下,让盒子居中

1
2
3
4
5
6
var winH=document.documentElement.clientHeight||document.body.clientHeight;
var winW=document.documentElement.clientWigth||document.body.clientWigth;
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,没有其他的
clientTop:盒子上边框的高度
clientLeft:盒子左边框的宽度
通过JS盒子模型获取的结果是不带单位的,而且只能是整数,(他会自动四舍五入)

offset

offsetWidth 和 offsetHeight

在clientHeight和clientWidth的基础上加上了边框的长度;
offsetWidth=clientWidth+左右边框(border)
offsetHight=clienthight+上下边框
真实项目中,如果想要得到盒子的宽度和高度一般都用offsetWidth和offsetHeight,这样就包含了盒子的边框

1
2
3
4
5
6
var winH=document.documentElement.offsetHeight||document.bodyElement.offsetHeight;
var winW=document.documentElement.offsetWigth||document.bodyElement.offsetclientWigth;
var boxW=box.offsetWidth;
var boxH=box.offsetHeight;
box.style.left=(winW-boxW)/2+'px';
box.style.top=(winH-boxH)/2+'px';

offssetParent

当前和盒子的父级参照物(得到父级参照物元素)

父级参照物不等价于父级元素,与父级元素没有直接关系
父级参照物:同一平面中最外层容器是所有里层盒子的父级参照物
一般情况下,一个页面所有元素的父级参照物都是body,body没有父级参照物;

当我们给元素设置定位(会让元素脱离文档流)的时候,会改变父级参照物(不在一个平面上)

offsetTop&offsetLeft:
当前元素外边框距离父级参照物的内边框的偏移量
(标准IE8浏览器特殊性: 当前元素最外边框距离父级参照物的外边框的偏移里量 )
window.navigator.userAgent 获取浏览器的版本号

获取页面中任何一个元素距离body的左偏移和上偏移,不知道该元素的具体位置。
思路:

首先获取自己的偏移量及父级参照物
如果父级参照物不是body,我们加上父级参照物的边框和偏移量。。。一直加到父级参照物为body的元素为止

scroll

scrollHeight && scrollWidth

没有内容溢出:获取的结果和clientWidth、clientHeight的结果相同;
有内容溢出:真实内容的宽度或高度,包含溢出内容的值,再加上padding或左padding的值
scrollWidth&&scrollHeight获取的是约等于的值
由于内容溢出,每个浏览器对于行高或文字的渲染不一样,回去的结果也不一样
是否设置overflow:hidden对最后的结果也有影响

获取当前页面的真实高度(包含溢出)

1
document.documentElement.scrollWidth||document.body.scrollHight

scrollLeft && scrollTop

横向或竖向滚动条卷去的宽度或高度
(在拉动滚动条时,上面的内容会被卷去,就是scrollTop)

  • 最小值:0
  • 最大值:scrollHight-clientHight:真实页面高度-一屏幕的高度
  • 前面的JS盒子模型的属性都是只读属性,只能获取,不能修改;而scrollTop&&scrollLeft可读写属性,既可以获取,也可以修改;

window.onscroll

window.onscroll:浏览器滚动条滚动事件(只要滚动就会触发该事件)

* 1、鼠标滚轮控制 或者 手动拖动滚动条

* 2、键盘按键控制

* 3、使用JS代码控制

* …

* 不管什么方式,只要滚动条动了就会触发这个事件

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

通过JS盒子模型12个属性(不包含offsetParent)获取的结果都是整数,没有单位,如果有小数,浏览器会自动四舍五入
通过JS盒子模型 属性获得的值都是组合值,不能单独获取某一个具体样式值

curEle.style.xxx;

获取当前元素所有写在行内样式上的样式值(如果样式没有设置在行内元素上 得到空字符串)
特殊:只有把样式写在行内样式上,才可以通过这种方法获取到=》这种方法在真实项目中比较少见,因为我们很少在行内样式上写样式

window.getComputedStyle && curEle.currentStyle

只要当前元素在页面中显示出来,我们就可以获得其样式值(不管是行内还是样式表),也就是获取所有经过浏览器计算过的值,包括你没有写浏览器默认设置的值。
window.getComputedStyle:适用于标准浏览器,IE6-8不兼容,在IE6-8的Window全局对象中,没有提供getComputedStyle这个属性和方法,我们使用curEle.currentStyle来获取需要的样式值

//通过getComputedStyle获得的结果是一个对象,包含当前元素所有的样式属性和属性值

语法:window.getComputedStyle([当前需要操作的元素],[当前元素的伪类,一般写null])
window.getComputedStyle(box,null).paddingleft;

//通过 curEle.currentStyle来获取样式
box.currentStyle.paddingleft;

封装一个公共的方法:getCss

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//getCSS:获取当前元素某一个样式的属性值
//@parameter curEle:当前需要操作的元素
//attr:要获取样式的属性名
function getCss(curEle,attr){
var value=null;
var reg=null;
try{
value=window.getComputedStyle(cueEle,null)[attr];
}
catch(e){
value=curEle.currentStyle
}
reg=/^-?\d+(\.\d+)?(px|pt|em|rem)?$/i;//去除单位
reg.test(value)?value=parseFloat(value):null;
return value;
}
console.log(getCss(box,'display'));

方法二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function getCss(curEle, attr) {
var value = null,
reg = null;
if ('getComputedStyle' in window) {
value = window.getComputedStyle(curEle, null)[attr];
} else {
value = curEle.currentStyle[attr];
}
//=>去除单位
reg = /^-?\d+(\.\d+)?(px|pt|rem|em)?$/i;
reg.test(value) ? value = parseFloat(value) : null;
return value;
}
console.log(getCss(box, 'display'));

设置元素的样式

curEle.style.xx=xxx;设置当前元素的行内样式;(JS设置样式一般都设置在行内样式上,因为行内样式优先级最大)(JS操作属性不支持-,所有-改成下一个单词大写)
curEle.className=xxx;设置元素的样式类名;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
curEle['style'][attr]=value;
//传递value值,如果没有单位,需要补单位
//并不是所有的值都需要补单位,
//传递的值带单位,不需要不单位

if(attr==='opacity'){
curEle.style.opacity=value;
curEle.style.filter='alpha(opacity='+value*100%');
} !isNaN(value)&&!/^(zoom|lineHeight|zIndex|fontWeight)$/i.test(value)?value+='px':null;
curEle['style'][attr]=value;
}
setCss(box,'padding','20px');
将3个方法封装在一个里面
var css = function () {
var len = arguments.length,
type = Object.prototype.toString.call(arguments[1]),
fn = getCss;
len >= 3 ? fn = setCss : (len === 2 && type === '[object Object]' ? fn = setGroupCss : null);
return fn.apply(this, arguments);
};

children

不管在什么浏览器中,都可以获得当前元素的子节点,(元素节点)
但在IE6-8下,也会将注释节点获取到,因此有所差别

1
2
3
function children(curEle){

}

编程常用方法:假设法 排除法

JS中的动画

1、步长偿固定,完成时间不固定
2、固定时间动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function linear(t, b, c, d) {
return t / d * c + b;
}
var oBox = document.getElementById('box');
var time = 0,//已经运动的时间
duration = 1000,//总时间
begin = utils.css(oBox, 'left'),//左边距
target = utils.winBox('clientWidth') - oBox.offsetWidth,//目的地
change = target - begin;//总共需要走的距离
var timer = setInterval(function () {
time += 17;
if (time >= duration) {
utils.css(oBox, 'left', target);
clearInterval(timer);
return;
}
var curL = linear(time, begin, change, duration);
utils.css(oBox, 'left', curL);
}, 17);

图片懒加载原理:

1、IMG标签的SRC不存放图片的地址(如果存放真实的地址,页面一加载图片肯定就加载出来了),我们把真实图片的地址存储在当前IMG标签的自定义属性上(DATA-IMG)
2、为了保证当前图片没有真实地址的时候,浏览器中不会出现叉叉或者出现ALT中的内容,我们一般都会把图片先隐藏(display:none opacity:0…),等到后期把真实图片加载出来,在让当前图片展示
3、看不到真实图片了,我们最好给一个占位图片(占位图:要求一定要很小,最好是1KB):我们在IMG外面包一层DIV盒子,把占位图赋值给当前盒子的背景图片来处理

=>开始IMG不显示,展示的是默认的背景图,当IMG真实地址加载完成后,我们让IMG显示,此时真实图片会覆盖住背景图

坚持原创技术分享,您的支持将鼓励我继续创作!