DOM
DOM( Document Object Model),文档对象模型,DOM可以以一种独立于平台和语言的方式访问和修改一个文档的内容和结构。换句话说,这是表示和处理一个HTML或XML文档的常用方法。
Dom技术使得用户页面可以动态地变化,如可以动态地显示或隐藏一个元素,改变它们的属性,增加一个元素等,Dom技术使得页面的交互性大大地增强。
要改变页面的某个东西,JavaScript 就需要获得对 HTML 文档中所有元素进行访问的入口。这个入口,连同对 HTML 元素进行添加、移动、改变或移除的方法和属性,都是通过文档对象模型来获得的DOM。
DOM将整个页面映射为一个由层次节点组成的文件。有1级、2级、3级共3个级别。
1级DOM
DOM核心(提供了同时操作HTML文档和XML文档的公共属性和方法)和DOM HTML两个模块组成。
DOM核心能映射以XML为基础的文档结构,允许获取和操作文档的任意部分。DOM HTML通过添加HTML专用的对象与函数对DOM核心进行了扩展。
2级DOM
2级DOM对1级DOM的核心进行了扩展。
2级DOM引进了几个新DOM模块来处理新的接口类型:
DOM视图:描述跟踪一个文档的各种视图(使用CSS样式设计文档前后)的接口;
DOM事件:描述事件接口;
DOM样式:描述处理基于CSS样式的接口;
DOM遍历与范围:描述遍历和操作文档树的接口。
3级DOM
3级DOM通过引入统一方式载入和保存文档和文档验证方法对DOM进行进一步扩展,DOM3包含一个名为“DOM载入与保存”的新模块
DOM中的节点
DOM 是这样规定的:
整个文档是一个文档节点
每个 HTML 标签是一个元素节点
包含在 HTML 元素中的文本是文本节点
每一个 HTML 属性是一个属性节点
注释属于注释节点
DOM优点及缺点
DOM的优势:易用性强,使用DOM时,将把所有的XML文档信息都存于内存中,并且遍历简单,支持XPath,增强了易用性。
DOM的缺点:效率低,解析速度慢,内存占用量过高,对于大文件来说几乎不可能使用。另外效率低还表现在大量的消耗时间,因为使用DOM进行解析时,将为文档的每个element、attribute、processing-instruction和comment都创建一个对象,这样在DOM机制中所运用的大量对象的创建和销毁无疑会影响其效率。
DOM优化
优化DOM的本质其实就是减少DOM树的重流与重绘。
那么我们先来说说DOM的重流和重绘
通常页面在加载你的js,css,img等文件时,引擎会对文件加以解析,最终生成两颗树,渲染树和DOM树.
DOM树中的需要显示节点在渲染树中都会存在,但是display:none的则不会存在。 可以说,渲染树是指定DOM显示的真实节点,而DOM树则是页面显示的HTML结构。
在渲染树中,常常将节点成为帧或者盒子。这里,也可以理解为渲染树,其实就是css文件指定节点的样式表。
当渲染树和DOM树都已经完成的时候,则开始将页面显示到桌面上了。
这时候,如果你改变页面的DOM结构,浏览器则会重新改动涉及到的DOM. 此时你的渲染树和DOM树就会发生改变。
浏览器会重新计算出渲染树这一过程叫做重流(重排).
将更新后的结构重新渲染到页面这一过程叫做重绘
改变页面的布局,大小,都会发生重流的情况,发生重流就一定会发生重绘。
优化DOM的结构:
其实也就是对引用保存,动画优化,节点保存,更新节点等基本操作进行优化。
1.首先当你过多的频繁操作DOM的时候,一定要记得保存。 而且,保存一定是要保存所有涉及DOM相关的操作。
2.DOM操作的优化,创建,查找,查看,移动节点,这些地方都可以优化。
3.当我们需要批量加入子节点的时候,就需要使用fragment这个虚拟片断,来作为一个容器.
DOM对象方法
getElementById() 返回带有指定 ID 的元素。
getElementsByTagName() 返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)。
getElementsByClassName()返回包含带有指定类名的所有元素的节点列表。
appendChild() 把新的子节点添加到指定节点。
removeChild() 删除子节点。
replaceChild() 替换子节点。
insertBefore() 在指定的子节点前面插入新的子节点。
createAttribute() 创建属性节点。
createElement() 创建元素节点。
createTextNode() 创建文本节点。
getAttribute() 返回指定的属性值。
setAttribute() 把指定属性设置或修改为指定的值。
<div id="p1" class="p1"></div>
</body>
<script>
var oP=document.getElementById("p1");
oP.getAttribute("id");//获取该阶段的属性:id
oP.setAttribute("id","Z-one");//设置一个属性。
oP.removeAttribute("id")//删除ID节点
</script>
属性
innerHTML属性
使用 innerHTML 属性是获取元素内容的最简单方法。
innerHTML 属性对于获取或替换 HTML 元素的内容
<p id="example">Welcome!</p>
<script>
var txt=document.getElementById("example").innerHTML;
console.log(txt);
// console.log(txt.firstChild.nodeValue); 获取第一个子节点的值
</script>
上面这个栗子getElementById()是一个方法,而innerHTML是一个属性
节点
nodeName属性
nodeName 是只读的,规定节点名字
元素节点的 nodeName 与标签名相同
属性节点的 nodeName 与属性名相同
文本节点的 nodeName 始终是 #text
文档节点的 nodeName 始终是 #document
nodeValue
元素节点的 nodeValue 是 undefined 或 null
文本节点的 nodeValue 是文本本身
属性节点的 nodeValue 是属性值
<span id="span">节点</span>
<script>
window.onload = function() {
var element = document.getElementById("span");
var text = element.firstChild;
var property = document.getElementById("span").getAttributeNode("id");
console.log("这是元素节点的返回值:"+ element.nodeName);//返回的标签名SPAN,注意是大写的
console.log("这是文本节点的返回值:"+ text.nodeName);//返回的#text
console.log("这是属性节点的返回值:"+ property.nodeName);//返回的是属性名,这里是id
console.log("这是元素节点的返回值:"+ element.nodeValue);//本身就没有意义,返回的是null
console.log("这是文本节点的返回值:"+ text.nodeValue);//返回的是文本值,返回的是节点
console.log("这是属性节点的返回值:"+ property.nodeValue);//返回的是属性值,这里是id的属性值 myspan
}
</script>
nodeType
nodeType返回节点的类型,是只读的
元素 1
属性 2
文本 3
注释 8
文档 9
firstChild:第一个子节点
lastChild:最后一个子节点
childNodes:子节点列表,是一个数组。
parentNode:父节点