

JS盒子模型13个属性
- 在JS中通过相关的属性可以获取(设置)元素的样式信息,这些属性就是盒子模型属性,基本上都是有关样式的
- CSS中内容的宽高:不含padding/border。设置box-sizing:border-bor,宽高代指是整个盒子的宽高(内容+padding+border)
- 在JS盒子模型13个属性中,只有scrollTop/scrollLeft是“可读写”属性,其余都是“只读”属性
client
- clientTop:上边框
- clientLeft:左边框
- clientWidth:内容宽度 + padding(左右),是否溢出不影响,是否设置overflow:hedden无关
- clientHeight:内容高度 + padding(上下),是否溢出不影响,是否设置overflow:hedden无关
offset
- offsetTop:上偏移值:元素上边框距离 父级参照物上边的距离 (x轴)
- offsetLeft:左偏移值:元素左边框距离 父级参照物左边距离(y轴)
- offstWidth:内容宽度 + padding(左右) + border(左右)
- offsetHeight:内容高度 + padding(上下) + border(上下)
- offsetParent:父级参照物默认是body,是可以修改的 通过position:absolute/relative/fixed
scroll
- scrollTop:纵向卷去距离
- scrollLeft:横向卷去距离
- scrollWidth:真实内容的宽度,溢出时只含padding(左),不溢出+padding(左右)。是否设置overflow:hidden不影响
- scrollHeight:真实内容的高度,溢出时致函padding(上),不溢出+padding(上下)。是否设置overflow:hidden不影响
兼容写法:前面为true执行,为false时执行后面
document.documentElement.clientWidth||document.body.clientWidth
document.doucmentElement.clientHeigth||docuemnt.body.clientHeight
获取当前页面的真实宽高(包含溢出的部分)
document.documentElement.scrollWidth||document.body.scrollWidth
document.doucmentElement.scrollHeigth||docuemnt.body.scrollHeight
需求任意元素距离body的便宜(不管参照物)
不管父级参照物是谁,都要获取当前元素距离Body的偏移量(左偏移和上偏移),不能修改既定的样式,不能基于position方式改它的参照物了
1、首先获取当前元素的左偏移
2、在这个基础上累加
A:父级参照物的边框
B:父级参照物的偏移
累加完父级,在找父级的父级(A),加上A的左边框和左偏移...,一直加到父级参照物是body位置
function offset(ele) {
let left = ele.offsetLeft; // 左偏移
let top = ele.offsetTop; // 上偏移
let parent = ele.offsetParent; //父级参照物
// 只要找到的父级参照物不是body 就继续往上查找(一直循环下去 一直到body为止)
//parent为true并转小写,不等于body时累计,等于body时不成立
while (parent && parent.nodeName.toLowerCase() !== "body") {
left += parent.offsetLeft + parent.clientLeft;
top += parent.offsetTop + parent.clientTop;
parent = parent.offsetParent;
}
return {
left,
top
}
}
通过JS盒模型属性获取值的特点
- 1、获取的都是数字不带单位
- 2、获取的都是整数,不会出现小数,一般都会四舍五入,尤其是获取的偏移量
- 3、获取的结果都是复合样式值,好几个元素样式组合在一起的值,如果只想获取单一样式值(例如:只想获取padding),盒子的模型属性获取不了(这不能说没有用,真实项目中,有时候我们就是需要获取组合的值来完成一些操作)
获取元素具体的某个样式值
- 1、元素.style.xxx操作获取。
弊端:只能获取所有写在元素行内上的样式,不写在行内上,不管你写没写都获取不到返回空,真实项目中我们很少会把样式写在行内上
- 2、获取当前元素所有经过浏览器计算的样式
经过计算的样式:只要当前元素可以在页面中呈现(或者浏览器渲染它了),那么它的样式都是被计算过的
不管当前样式写在哪
不管你是否写了(浏览器会给元素设置一些默认样式)
getAttribute获取属性值
- getAttribute()方法不能通过document对象调用,只能通过一个元素节点对象调用它。
<p title='1'>djdjdj</p>
var text=document.getElementsByTagName("p")
for (var i=0;i<text.length;i++){
alert(text[i].getAttribute("title"));//无返回null,有返回属性值
}
setAttribute设置修改添加属性名属性值
- setAttribute()方法只能通过元素节点对象调用的函数,需要传递两个参数
<p title='1'>djdjdj</p>
var text=document.getElementsByTagName("p");
text[0].setAttribute("title",'5');//行间属性有则是修改,无则是添加
默认JS封装CSS方法
公共方法库:项目中常用的一些方法,封装在这里(使用高级单例模式,把需要用的方法return暴露出去)
let utils = (function () {
//获取元素的样式
let getCss = function (curEle, attr) {
if (typeof window.getComputedStyle === 'undefined') {
//当前浏览器不兼容getComputedStyle,return,停止执行
return;
}
//抛出一个错误(语法错误),让浏览器崩溃,不在继续执行JS
throw new SyntaxError('您的浏览器版本过低,请升级到最新版本,谢谢配合')
let val = window.getComputedStyle(curEle, null)[attr];
reg = /^-?\d+(\.\d+)(px|rem|em|pt)$/i;
reg.test(val) ? val = parseFloat(val) : null;
return val;
};
//设置元素的样式
let setCss = function (curEle, attr, value) {
//如果需要考虑IE6~8兼容
//1、透明度这个样式在低版本浏览器中不是使用opacity,而是filter(我们两套都要设置)
//2、如果传递进来的value值没有带单位,我们根据情况设置px单位
//3、某些样式属性才会加单位:width/height/padding(4个方向)/margin(4个方向)/font-size/top/left/bottom/right...)。用户自己传递的value值中是没有单位的
// if(attr==='opacity'){
// curEle.style.opacity=value;
// curEle.style.filter=`alpha(opacity=${value*100})`;
// return;}
if (!isNaN(value)) {
//isNaN检测的结果是false:说明value是纯数字没单位,取反后为true执行块级作用域
let reg = /^(width|height|fontSize|((margin|padding)?(top|left|right|bottom)?))$/i;
reg.test(attr) ? value += 'px' : null;
}
curEle['style'][attr] = value;
};
//批量设置元素样式
let setGroupCss = function (curEle, options = {}) {
//遍历传递的options,有多少键值对,就循环多少次,每一次都调取setCss方法逐一设置即可
for (let attr in options) {
if (!options.hasOwnProperty(attr))break;
//options:传递进来的需要修改样式对象(集合)
//attr:每一次遍历到的集合中的某一项(要操作的样式属性名)
//options[attr]:传递的要操作的样式属性值
setCss(curEle, attr, options[attr]);
}
};
//CSS操作汇总
let CSS = function (...arg) {
let len = arg.length;
let fn = getCss;
len >= 3 ? fn = setCss : null;
len === 2 && (arg[1] instanceof Object) ? fn = setGroupCss : null;
return fn(...arg);
};
//把需要用的方法return暴露出去
return {
CSS //在ES6中直接这样写相当于CSS:CSS
}
})();
offsetParent/offsetTop/offsetLeft
- offsetTop/offsetLeft:获取当前盒子距离其父级参照物的偏移量(上偏移/左偏移)
- offsetparent:当前盒子的父级参照物
- 参照物:同一个平面中(同一层级中),元素的父级参照物和结构没有必然联系,默认他们的父级参照物都是body(当前平面最外层的盒子),body的父级参照物是null
- 参照物可以改变:构建出不同的平面即可,设置定位后元素脱离文档流,使用Zindex,但是这个属性只对定位有作用,所以改变元素的定位(position:relative/absolute/fixed),可以改变其父级参照物
<div id="outer">
<div id="inner">
<div id="center"></div>
</div>
</div>
outer.offsetParent;//body
inner.offsetParent;//body
center.offsetParent;//body
utils.css(outer,{
position:'relative';//把outer脱离原有的平面,独立出一个新的平面,后代元素的父级参照物都会以它为参考
});
console.log(outer.offsetParent);//body
console.log(inner.offsetParent);//outer
console.log(center.offsetParent);//outer
utils.css(inner,{
position:'relative';
})
console.log(outer.offsetParent);//body
console.log(inner.offsetParent);//outer
console.log(center.offsetParent);//inner
console.log(document.body.offsetParent);//null
offsetTop/offsetLeft
- offsetTop/offsetLeft:获取当前盒子距离其父级参照物的偏移量(上偏移/左偏移),当前盒子的外边框开始~父级参照物的内边框
<div id="outer">
<div id="inner">
<div id="center"></div>
</div>
</div>
utils.css(outer,{
position:'relative';////把outer脱离原有的平面,独立出一个新的平面,后代元素的父级参照物都会以它为参考
});
console.log(center.offsetLeft)//center的外边框开始~outer的内边框值(outer是父级参照,因为设置了定位后独立了一个新的平面)
console.log(inner.offsetLeft)//inner的外边框开始~outer的内边框值
cnosole.log(outer.offsetLeft)//outer的外边框开始~body的内边框值,因为它的参照物是body
scrollTop/scrollLeft
- scrollTop/scrollLeft:滚动条卷去的宽度和高度
- 最小卷去值:0
- 最大卷去值:真实页面的高度减去-屏幕的高度
- document.doucmentElement.scrollHeight-document.documentElemetn.clientHeight
- 操作浏览器的盒子模型属性,我们一般都要写两套,用来兼容各种模式下的浏览器
//操作浏览器盒子模型属性的,现在基本用不上
let winHandle=function(attr,value){
if(typeof value!=='undefined'){
//设置盒子模型属性值:scrollTop/scrollLeft
document.documentElement[attr]=value;
document.body[attr]=value;
return;
}
return document.documentElement[attr]||document.body[attr];
};