DOM
document object model 文档对象模型,它里面提供了一系列的属性和方法,能够让JS操作页面中的元素。
一个HTML有页面的组成如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM是什么</title>
</head>
<body>
<div></div>
</body>
</html>
其中出现了很多的标签,这些标签也被称为节点(Node),一个页面可以看做有很多的节点组成的,包括了常见的元素标签、文本、注释、空格、回车、换行符……都是节点。
获取dom8个元素方法
- document.getElementById(‘id名’)
- document.getElementsByTagName(‘标签名’)
- document.getElementsByClassName(‘类名’)(IE6-8下兼容)
- document.getElementsByName(‘属性值’)
- document.documentElement//html元素
- document.body//body元素
- document.querySelector(“一个css选择器”)
- document.querySelectorAll(“多个css选择器”)
节点的7个关系属性:
- childNodes:获取的是元素的所有子节点,包括注释、文字、标签、回车、空格。
- children:获取所有的标签节点。(在ie6-8下获取的值不准确会把注释节点当作元素节点来获取。)
- parentNode:获取元素的父亲节点。
- previousSibling:上一个哥哥节点。
- nextSibLing:下一个弟弟节点。
- firstChild:第一个子节点。
- lastChild:最后一个子节点。
可以将节点分为以下4中类型
4个类型 | nodeType | nodeName | nodeValue |
---|---|---|---|
元素节点 | 1 | 大写的标签名 | null |
文本节点 | 3 | #text | 文字的内容 |
注释节点 | 8 | #comment | 注释的内容 |
document | 9 | #document | null |
常用的操作dom元素9个方法
容器.appendChild(我们要添加的元素) 把我们创建的标签插到指定的容器(末尾)
oldVal.insertBefore(newVal,oldVal) 把一个元素添加另一个元素的前面
oldVal.replaceChild(newVal,oldVal) 一个元素把另一个元素替掉
元素.cloneNode() 把元素克隆一份 true(深度克隆) false
document.body.removeChild(我们要移除的元素)
setAttribute 设置元素的属性名 (会在html结构中体现出来)
getAttribute 获取元素的属性名
removeAttribute 移除元素的属性名
js中的盒子模型
通过一系列的属性来获取当前盒子的相关样式。 盒子模型中的,width和height指的是内容的宽高
client(可视)系列
clientWidth
=width+padding(left+right)
clientHeight
=height(不设置height就是指的是内容的高度)+padding(top+bottom)
clientLeft
:左边框高度
clientTop
:上边框高度
没有右边框和和下边框
这四个属性和内容是否溢出没有关系,因为client使可视区域,溢出的内容不在可视区域内,我们可以设置overflow:hidden来隐藏溢出的内容。
//获取当前页面的可视区域(一屏幕)的宽度和高度(和页面的内容是否溢出没有关系),部分浏览器不识别用document.documentElement来操作浏览器的一些盒子模型的属性,我们需要使用document.body来操作,所以需要写两套。
// document.documentElement.clientWidth||document.body.clientWidth
// document.documentElement.clientHeight||document.body.clientHeight
3、offsetWidth / offsetHeight:在clientWidth&clientHeight的基础上加上边框即可
获取HTML页面的真实宽高(包含溢出的内容) ‘约等于的值’
- document.documentElement.scrollWidth||document.body.scrollWidth
- document.documentElement.scrollHeight||document.body.scrollHeight
以上的JS属性都是在特定的情况下使用(他们获取的是复合值),如果想获取元素具体某一个样式属性的值,上述的属性就不合适了
获取元素具体的css样式
1、元素.style.样式属性
获取元素写在行内上的样式属性,重点记住只能获取写在行内的样式,如果写在样式表中这个操作是无法获取到的
2、getComputedStyle和currentStyle
获取当前元素的所有经过浏览器计算的样式
浏览器计算过的样式:只要当前元素能在页面中展示,那么他的样式都是经过浏览器计算的,不管你写在哪,以及你写不写(有些样式不写,浏览器也有默认样式)
getComputedStyle是window全局对象的一个属性方法,但是在ie6-8下浏览器红不存在这个属性,低版本浏览器中我们使用currentStyle来获取
[标准浏览器]
window.getComputedStyle([元素],[样式伪类,一般都用NULL]) 获取的结果是一个对象,存储了所有经过计算的样式
[元素].currentStyle 获取的结果也是一个对象,存储了所有经过计算的样式
offsetLeft / offsetTop / offsetParent
获取当前元素的 左偏移 / 上偏移 / 父级参照物
1、offsetParent:获取当前元素的父级参照物
在默认的情况下,BODY中出现的所有元素的父级参照物都是BODY(因为在同一个平面上),BODY本身的父级参照物是NULL
我们通过设置POSITION定位,可以让元素脱离文档流,从而改变元素的父级参照物(CSS中我们当前元素是相对于谁定位的,那么JS中它的父级参照物就是谁)
2、offsetLeft和offsetTop:当前元素距离其父级参照物的左偏移和上偏移
在大部分浏览器中,这个距离是从当前元素的外边框开始到父级参照物的内变框结束(不含父级元素的边框)
IE8(纯IE8,不是模拟器仿真),这个距离包含了父级参照物的边框,偏移量=当前元素的外边框到父级参照物的外边框
scroll系列
scrollTop 和 scrollLeft:
当前容器(一般都是当前页面)卷去的高度和宽度
学习的13个JS盒子模型属性,只有这两个属性是‘可读写’的(可以获取也可以设置),而其余的11个属性都是‘只读’的
为了兼容浏览器,我们设置或者获取页面的盒子模型属性值的时候,都要写两套
有最小值,最小值是零,设置的值小于零也没用
有最大值,真实页面的高度document.documentElement.scrollHeight||document.body.scrollHeight - 可是窗口的高度document.documentElement.clientHeight||document.body.clientHeight
scrollWidth / scrollHeight
没有内容溢出的情况下
- scrollWidth = clientWidth
- scrollHeight = clientHeight
有内容溢出的情况下
- scrollHeight = paddingTop + 真实内容的高度(包含溢出的内容)
- scrollWidth = paddingLeft + 真实内容的宽度(包含溢出的内容)
是否设置OVERFLOW:HIDDEN对获取的结果是产生影响的,而且每个浏览器获取的结果也还都不太一样,所以我们的这两个属性值,在有内容溢出的情况下,我们获取的值都是约等于的值
dom映射
通过dom方法获取的是一个元素集合(类数组),这个集合仍然和页面中的元素保持着联系,这个集合会随着页面中元素(节点)的增加而增加,减少而减少,即使把这个类数组转换为数组,每个元素都和页面之间都存在着一定的联系。
dom回流
元素的位置发生改变(增加元素,删除元素,移动)引起回流,让整个页面重新渲染一遍,从而造成性能浪费
在项目当中要尽可能的减少回流发生下面以商品的上架时间排序为例:
function sortGoods() {
//->排序
mallList.sort(function (cur, next) {
var curTime = cur.getAttribute('data-time');
var nextTime = next.getAttribute('data-time');
//"2017-03-15" VS "2017-02-08" =>把每一个时间的‘-’都去掉,然后比较数字的大小即可
curTime = curTime.replace(/-/g, '');
nextTime = nextTime.replace(/-/g, '');
return curTime - nextTime;
});
//->把当前最新的数据重新的增加到页面中,以此更改页面中内容的顺序
var frg = document.createDocumentFragment();
//由于对页面中的元素进行了排序操作会出发dom回流,操作的次数越多,触发的回流也就越多,导致页面加载性能差,在这里我们创建了一个临时变量frg
for (var i = 0; i < mallList.length; i++) {
frg.appendChild(mallList[i]);
}
//将排序之后的内容全部放在创建的文档碎片中
mallItem.appendChild(frg);
//最后一次性的将内容添加也页面当中,回流也就只触发一次,这样就大大的提高了性能,
frg = null;
}
sortGoods();
dom重绘
元素样式发生改变,就会把当前这个元素重新渲染一遍所以在以后项目中,能用重绘代替的就不用回流,能用一次回流就不用使用多次