JS盒子模型常用属性
CSS如下:
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#box{
margin: 100px;
padding: 30px;
width: 200px;
height: 200px;
border: 30px solid royalblue;
}
</style>
HTML如下:
<body>
<div id="box" class="test00 test01 test02 test03" name="aaa" index="0">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut corporis facere libero nulla numquam possimus provident quae quisquam. Accusantium commodi culpa dolores esse excepturi maxime praesentium recusandae sapiente sit voluptates.
</div>
</body>
小技巧:自动生成随机文本
使用方法:在div元素中书写lorem或lorem + 单词数量 (不加单词数量则生成默认长段随机文本)
使用这个功能可以帮助我们生成随机文本,不必费力的去找填充文本。
Lorem ipsum,中文又称“乱数假文”, 是指一篇常用于排版设计领域的拉丁文文章 [1] ,主要的目的为测试文章或文字在不同字型、版型下看起来的效果。
Lorem ipsum从西元15世纪开始就被广泛地使用在西方的印刷、设计领域中,在电脑排版盛行之后,这段被传统印刷产业使用几百年的无意义文字又再度流行。由于这段文字以“Lorem ipsum”起头,并且常被用于标题的测试中,所以一般称为Lorem ipsum,简称为Lipsum。 ---参考百度百科
1、JS盒子模型指的是通过JS中提供的一系列属性和方法,获取页面中元素的样式信息值
<script>
var box = document.getElementById('box');
console.dir(box);
</script>
div#box(这个元素有很多自己的私有属性)通过这个元素所属的类的原型找到原型链上公共的属性和方法。
原型链如下:
div#box => HTMLDivElement.prototype => HTMLElement.prototype => Element.prototype =>Node.prototype => EvenTarget.prototype => Object.prototype
1) Element.attributes
Element.attributes 属性返回该元素所有属性节点的一个实时集合。该集合是一个 NamedNodeMap 对象,不是一个数组,所以它没有 数组 的方法,其包含的 属性 节点的索引顺序随浏览器不同而不同。更确切地说,attributes 是字符串形式的名/值对,每一对名/值对对应一个属性节点。
NamedNodeMap
NamedNodeMap 接口表示属性节点 Attr 对象的集合。尽管在 NamedNodeMap 里面的对象可以像数组一样通过索引来访问,但是它和 NodeList 不一样,对象的顺序没有指定。
NamedNodeMap 对象是即时的(live),因此,如果它内部包含的对象发生改变的话,该对象会自动更新到最新的状态。
也就是说attributes属性除了拥有自己的属性,还继承了它内置类NameNodeMap上的方法。
走一个测试下这些方法
- NamedNodeMap.getNamedItem(属性名) 通过属性名获取属性节点(Attr)。
box.attributes.getNamedItem('name')
//=> name='aaa'
- NamedNodeMap.item() 通过索引获取属性节点(Attr),或者,当索引超出或等于属性节点的数量时,返回 null。
box.attributes.item(0)
//=> id='box'
- NamedNodeMap.removeNamedItem(属性名) 移除一个属性节点(Attr)。
box.attributes.removeNamedItem('id') //名为id的属性节点被删除
- NamedNodeMap.setNamedItem(node) 替换或添加一个属性节点(Attr)到映射(map)中。
如果此节点已存在,则将替换该节点,并返回被替换的节点,否则返回值是 null。
//创建属性节点
var typ = document.createAttribute('id');
//添加属性值
typ.nodeValue = 'box';
//添加属性节点到元素上
box.attributes.setNamedItem(typ);
2) classList 和className
classList 和className的区别
Element.classList 是一个只读属性,返回一个元素的类属性的实时DOMTokenList 集合。
使用 classList 是替代element.className作为空格分隔的字符串访问元素的类列表的一种方便的方法。
className 获取或设置指定元素的class属性的值。
- 设置新的class属性值会把原先的覆盖掉
let cName = elementNodeReference.className;
elementNodeReference.className = cName;
- cName是一个字符串变量,表示当前元素的class属性的值,可以是由空格分隔的多个class属性值.
Element.classList 的方法
add( String [, String] )
添加指定的类值。如果这些类已经存在于元素的属性中,那么它们将被忽略。
box.classList.add('test004')
remove( String [,String] )
删除指定的类值。
box.classList.remove('test001')
client系列(当前元素的几个私有属性)
clientWidth / clientHeight 内容宽度/高度 + 左右/上下填充(也就是padding值)
内容的宽度和高度:我们设置的width和height这两个样式就是内容的宽度和高度,如果没设置height值,容器高度会根据里面的内容自适应,这样获取的值就是真实内容的宽度和高度。
如果设置了height值,不论内容多了还是少了,内容的高度就是设置的height值
真实内容的宽度和高度:代指的是内容的实际宽高(和我们设置的width和height没有必然的联系)
比如:只设置容器width=200px ;height=200px,如果里面的放了10万个字,就会内容溢出,而height还是原来的height,等于200px;那么文字内容就等于它溢出的高度+容器设置height值。
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#box{
margin: 100px;
padding: 30px;
width: 200px;
/*height: 200px;*/
border: 30px solid royalblue;
}
</style>
</head>
<body>
<div id="box" class=" " name="aaa" index="0">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut corporis facere libero nulla numquam possimus provident quae quisquam. Accusantium commodi culpa dolores esse excepturi maxime.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus at cupiditate delectus, eligendi excepturi explicabo, harum illum maxime minima minus quae quibusdam ratione saepe, sunt suscipit temporibus ullam vero voluptatibus.
</div>
<script>
var box = document.getElementById('box');
console.log(box.clientWidth); // = > 260
console.log(box.clientHeight); // => 480
</script>
</body>
clientLeft 和 clientTop
clientLeft:左边框的宽度 clientTop:上边框的高度 (就是border[left/top]Width)
3)offset系列
offsetWidth / offsetHeight
offsetWidth = clientWidth + clientLeft
*
2 ( 左右边框宽度)
offsetHeight = clientWidth + clientTop*
2 ( 上下边框高度)
offsetParent
当前元素的父级参照物
offsetLfet / offsetHeight
当前元素的外边框距离父级参照物的内边框的偏移量
4)scroll系列
scrollWidth / scrollHeight
和clientWidth / clientHeight 一样(前提是:容器中内容没有溢出的情况下)
如果容器中的内容溢出,我们获取的结果如以下规则:
scrollWidth:真实内容的宽度(包含溢出)+ 左填充(padding-left)
scrollWidth:真实内容的高度(包含溢出)+ 上填充(padding-top)
获取到结果都是约等于的值
容器是否设置overflow=‘hidden’对于最终的结果是有影响的;在不同浏览器中获取的结果也不是相同的
scrollLeft / scrollTop
表示滚动条卷去的宽度/高度
关于JS盒子模型的取值问题
如果宽度/高度设置值带有小数位,用这13个属性去获取值,不会出现小数,都会四舍五入取整
关于操作浏览器本身的盒子模型信息
document.documentElement.clientWidth / document.documentElement.clientHeight
是当前浏览器可视窗口的宽度和高度(一屏幕的宽度和高度)
document.documentElement.scrollWidth / document.documentElement.scrollWidth
是当前页面的真实宽度和高度【所有屏加起来(也就是页面很长出现了滚动条)的宽度和高度,是一个约等于值】
操作浏览器盒子模型的方法
兼容性比较好的写法
document.documentElement[attr] || document.body[attr];
document.documentElement[attr] 必须写在前面,[attr]表示要获取或设置的属性
例如:获取滚动条卷去页面的高度scrollHeight
document.documentElement.scrollHeight || document.body.scrollHeight;
//如果只传递了attr没有传value,默认“获取”
//如果两个参数都传递了,则为“设置”
代码如下:
function win(attr,value) {
if (typeof value === 'undefined'){
return document.documentElement[attr] || document.body[attr]; // [attr]表示属性名
}
document.documentElement[attr] = value;
document.body[attr] = value;
}
获取元素的某一个具体的样式的属性值需要注意事情
1、元素.style.属性名
这中方式需要把元素的样式都写在行内样式上才可以(写在样式中是不管用的)
2、使用window.getComputedStyle()
Window.getComputedStyle()方法返回一个对象,该对象在应用活动样式表并解析这些值可能包含的任何基本计算后报告元素的所有CSS属性的值。 私有的CSS属性值可以通过对象提供的API或通过简单地使用CSS属性名称进行索引来访问。
可以简单理解为,获取所有经过浏览器计算过的样式集合
语法
let style = window.getComputedStyle(element, [pseudoElt]);
比如:window.getComputedStyle(el,null).color
参数element
用于获取计算样式的
Element
参数pseudoElt
指定一个要匹配的伪元素的字符串。必须对普通元素省略(或null)。null 的意思是不返回伪类元素
返回的style
是一个实时的CSSStyleDeclaration
对象,当元素的样式更改时,它会自动更新本身。
CSSStyleDeclaration 表示一个CSS属性键值对的集合。CSSStyleDeclaration也是由window.getComputedStyle()返回的只读接口
浏览器兼容性
在IE6~8 下不兼容,因为window下没有
getComputedStyle
这个属性,可以使用currentStyle
来获取
语法:ele.currentStyle.attr
官方的提醒:该特性是非标准的,请尽量不要在生产环境中使用它!
【方法使用】使用window.getComputedStyle()获取伪元素属性的值
HTML如下:
<div class="box">
<p id="boxp">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam animi, at aut consequatur doloribus expedita facere hic libero pariatur, quae quibusdam tempora temporibus totam unde voluptatum! Amet debitis eius tenetur?
</p>
</div>
CSS如下:
*{
margin: 0;
padding: 0;
font-family: sans-serif;
font-size: 14px;
}
.box{
margin:20px auto;
width:300px;
padding: 20px;
border: 1px dashed #cccccc;
}
.box p{
line-height: 1.5;
}
/*:before :after ->在一个元素标签的前面或者后面,创建一个新的虚拟标签
可以给这个虚拟的标签增加样式和内容。
*/
.box p:before{
display: block;
height: 30px;
line-height: 30px;
text-align: center;
content: 'lorem';
background: royalblue;
color: #ffffff;
}
.box p:after{
display: block;
height: 30px;
line-height: 30px;
text-align: center;
content: 'lorem';
background: royalblue;
color: #ffffff;
}
JS如下:
var boxp = document.getElementById('boxp');
window.getComputedStyle(boxp, 'after').content = 'hello 123' ; //=> Uncaught DOMException: Failed to set the 'content' property on 'CSSStyleDeclaration'
//报错:CSSStyleDeclaration是一个CSS属性键值对的集合,只读接口不允许修改CSS属性的值
console.log(window.getComputedStyle(boxp, 'after').content); // => "lorem"
【方法使用】 获取当前元素所有经过浏览器计算过的样式中的[attr]对应的值
1、使用try、catch来处理兼容
前提:必须保证try中的代码块在不兼容浏览器中执行的时候报错,才可以用catch捕获到异常信息,进行其它处理,不管是什么浏览器,都需要先执行try中的代码块(消耗性能)
function getCss(curEle, attr) {
var val = null;
try {
val = window.getComputedStyle(curEle,null)[attr];
}catch(e){
val = curEle.currentStyle[attr];
}
return val;
}
2、判断当前浏览器中是否存在这个属性或者方法
function getCss(curEle, attr) {
var val = null;
if ('getComputedStyle' in window) {
val = window.getComputedStyle(curEle,null)[attr];
}else {
val = curEle.currentStyle[attr];
}
return val;
}
3、获取到当前的浏览器是IE6~8
function getCss(curEle, attr) {
var val = null;
if (/MSIE (6|7|8)/.test(navigator.userAgent)) {
val = curEle.currentStyle[attr];
}else {
val = window.getComputedStyle(curEle,null)[attr];
}
return val;
}
改进1.0:把获取的样式值单位去掉
function getCss(curEle, attr) {
var val = null;
if ('getComputedStyle' in window) {
val = window.getComputedStyle(curEle,null)[attr];
}else {
val = curEle.currentStyle[attr];
}
return parseFloat(val); //return parseFloat(val) 对于某些样式属性的值是不能去掉单位的,例如:float、position、margin、padding、border这些复合值、background...
}
function getCss(curEle, attr) {
var val = null, reg = null;
if ('getComputedStyle' in window) {
val = window.getComputedStyle(curEle, null)[attr];
} else {
val = curEle.currentStyle[attr];
}
reg = /^(-?\d+(\.\d+)?)(px|pt|rem|em)$/;
return reg.test(val) ? parseFloat(val) : val;
}
改进2.0:解决某些样式属性在不同浏览器中不兼容问题,比如:opacity
function getCss(curEle, attr) {
var val = null, reg = null;
if ('getComputedStyle' in window) {
val = window.getComputedStyle(curEle, null)[attr];
} else {
if (attr === 'opacity') {
val = curEle.currentStyle['filter'];
reg = /^alpha\(opacity=(\d+(?:\.\d+)?)\)$/i;
val = reg.test(val)?reg.exec(val)[1]/100:1;
}else {
val = curEle.currentStyle[attr];
}
}
reg = /^(-?\d+(\.\d+)?)(px|pt|rem|em)$/;
return reg.test(val) ? parseFloat(val) : val;
}