文档对象模型
文档对象模型(doucment object model,dom)是表示文档(如html文档、xml文档)和访问、操作构成文档的各种元素的应用程序接口。在dom中,html文档的层次结构被表示成树形结构。树的节点表示文档中的各种内容。
Node类型
Node是一个接口,中文叫节点,很多类型的DOM元素都是继承于它,都共享着相同的基本属性和方法。常见的Node有 element,text,attribute,comment,document 等(所以要注意 节点 和 元素 的区别,元素属于节点的一种)。
Node有一个属性 nodeType 表示Node的类型,它是一个整数,其数值分别表示相应的Node类型,具体如下:
- Node.ELEMENT_NODE:1
- Node.ATTRIBUTE_NODE:2
- Node.TEXT_NODE:3
- Node.CDATA_SECTION_NODE:4
- Node.ENTITY_REFERENCE_NODE:5
- Node.ENTITY_NODE:6
- Node.PROCESSING_INSTRUCTION_NODE:7
- Node.COMMENT_NODE:8
- Node.DOCUMENT_NODE:9
- Node.DOCUMENT_TYPE_NODE:10
- Node.DOCUMENT_FRAGMENT_NODE:11
- Node.NOTATION_NODE:12
假设我们要判断一个Node是不是元素,我们可以这样判断
if(someNode.nodeType == 1){
console.log("Node is a element");
}
这些Node类型中,我们最常用的就是element,text,attribute,comment,document这几种类型:
- Element提供了对元素标签名,子节点和特性的访问;
- Text表示文本节点,它包含的是纯文本内容,不能包含html代码,但可以包含转义后的html代码;
- Attr类型表示元素的特性,相当于元素的attributes属性中的节点;
- Comment表示HTML文档中的注释;
- Document表示文档,在浏览器中,document对象是HTMLDocument的一个实例,表示整个页面,它同时也是window对象的一个属性;
节点创建型api
1. createElement
createElement通过传入指定的一个标签名来创建一个元素,使用如下:
var newDiv = document.createElement("div");
2. createTextNode
createTextNode用来创建一个文本节点,使用如下:
var newtext = document.createTextNode("动态添加一些文本");
3. cloneNode
cloneNode方法返回调用该方法的节点的一个副本,使用如下:
var p = document.getElementById("para1"),
var p_prime = p.cloneNode(true);
p_prime.id = "p_prime";
注意:为了防止一个文档中出现两个ID重复的元素,使用cloneNode()方法克隆的节点在需要时应该指定另外一个与原ID值不同的ID
4.createDocumentFragment
DocumentFragment是DOM节点。它们不是主DOM树的一部分。通常的用例是创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。在DOM树中,文档片段被其所有的子元素所代替。
因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面回流。因此,使用文档片段document fragments 通常会起到优化性能的作用。使用如下:
document.getElementById("btnAdd").onclick = function(){
var list = document.getElementById("list");
var fragment = document.createDocumentFragment();
for(var i = 0;i < 100; i++){
var li = document.createElement("li");
li.textContent = i;
fragment.appendChild(li);
}
list.appendChild(fragment);
}
页面修改型API
创建型api它们只是创建节点,并没有真正修改到页面内容,而是要调用appendChild来将其添加到文档树中。
修改页面内容的api主要包括:appendChild,insertBefore,removeChild,replaceChild。
1.appendChild
appendChild方法将一个节点添加到指定父节点的子节点列表末尾,调用方法如下:
// 创建一个新的段落p元素,然后添加到body的最尾部
var p = document.createElement("p");
document.body.appendChild(p);
如果被插入的节点已经存在于当前文档的文档树中,则那个节点会首先从原先的位置移除,然后再插入到新的位置.
2.insertBefore
insertBefore方法在参考节点之前插入一个节点作为一个指定父节点的子节点。
var insertedElement = parentElement.insertBefore(newElement, referenceElement);
如果referenceElement为null则newElement将被插入到子节点的末尾。如果newElement已经在DOM树中,newElement首先会从DOM树中移除。
- insertedElement 是被插入的节点,即 newElement
- parentElement 是新插入节点的父节点
- newElement 是被插入的节点
- referenceElement 在插入newElement之前的那个节点
- 如果referenceElement为null则newElement将被插入到子节点的末尾。如果newElement已经在DOM树中,newElement首先会从DOM树中移除。
例子:
<div id="parentElement">
<span id="childElement">foo bar</span>
</div>
<script>
var sp1 = document.createElement("span");
var sp2 = document.getElementById("childElement");
var parentDiv = sp2.parentNode;
parentDiv.insertBefore(sp1, sp2);
</script>
3.removeChild
removeChild方法从DOM中删除一个子节点。返回删除的节点。
var oldChild = node.removeChild(child);
- child是要移除的那个子节点.
- node是child`的父节点.
- oldChild保存对删除的子节点的引用oldChild === child.
被移除的这个子节点仍然存在于内存中,只是没有添加到当前文档的DOM树中,因此,你还可以把这个节点重新添加回文档中,当然,实现要用另外一个变量来保存这个节点的引用. 如果使用上述语法中的第二种方法, 即没有使用 oldChild 来保存对这个节点的引用, 则认为被移除的节点已经是无用的。
4.replaceChild
用指定的节点替换当前节点的一个子节点,并返回被替换掉的节点。
var replacedNode = parentNode.replaceChild(newChild, oldChild);
- newChild 用来替换 oldChild 的新节点。如果该节点已经存在于DOM树中,则它会被从原始位置删除。
- oldChild 被替换掉的原始节点。
- replacedNode 和oldChild相等。
节点查询型API
1.document.getElementById
返回一个匹配特定 ID,如果不存在该元素,则返回null。
var element = document.getElementById(id);
- element是一个Element 对象。如果当前文档中拥有特定ID的元素不存在则返回null.
- id是大小写敏感的字符串,代表了所要查找的元素的唯一ID。所以document.getElementById("Main")无法获取到元素<div id="main">,因为'M'和'm'是不一样的。
2.document.getElementsByTagName
这个接口根据元素标签名获取元素,返回一个即时的HTMLCollection类型。
var elements = document.getElementsByTagName(name);
- elements是一个由发现的元素出现在树中的顺序构成的动态的HTML集合 HTMLCollection
- name 是一个代表元素的名称的字符串。特殊字符 "*" 代表了所有元素。
3.document.getElementsByName
getElementsByName主要是通过指定的name属性来获取元素,它返回一个即时的NodeList对象。
var elements = document.getElementsByName(name)
- elements是一个NodeList对象是一个节点的集合
- name是元素的name属性的值。
4.document.getElementsByClassName
返回一个包含了所有指定类名的子元素的类数组对象。当在document对象上调用时,会搜索整个DOM文档,包含根节点。你也可以在任意元素上调用getElementsByClassName()方法,它将返回的是以当前元素为根节点,所有指定类名的子元素。
var elements = document.getElementsByClassName(names);
- elements 是一个实时集合,包含了找到的所有元素。
- names 是一个字符串,表示要匹配的类名列表;类名通过空格分隔
- getElementsByClassName 可以在任何元素上调用,不仅仅是 document。 调用这个方法的元素将作为本次查找的根元素.
5.document.querySelector
返回文档中匹配指定的选择器组的第一个元素(使用深度优先先序遍历文档的节点 | 并且通过文档标记中的第一个元素,并按照子节点数量的顺序迭代顺序节点)。
var element = document.querySelector(selectors);
- element 是一个element 对象(DOM 元素)。
- selectors是一个字符串,包含一个或是多个CSS 选择器,多个则以逗号分隔。
如果没有找到匹配元素,则返回 null,如果找到多个匹配元素,则返回第一个匹配到的元素。
如果选择器是一个 ID,并且这个 ID 在文档中错误地使用了多次,那么返回第一个匹配该 ID 的元素。
6.document.querySelectorAll
返回与指定的选择器组匹配的文档中的元素列表 (使用深度优先的先序遍历文档的节点)。返回的对象是 NodeList。
var elementList = document.querySelectorAll(selectors);
- elementList 是一个静态的NodeList 类型的对象.
- selectors是一个由逗号连接的包含一个或多个CSS选择器的字符串.
- 如果selectors参数中包含CSS伪元素,则返回一个空的elementList。
元素属性型api
1.setAttribute
设置指定元素上的一个属性值。如果属性已经存在,则更新该值; 否则将添加一个新的属性用指定的名称和值。
element.setAttribute(name, value);
- name 是表示属性名称的字符串
- value 是属性的新值
2.getAttribute
getAttribute() 返回元素上一个指定的属性值。如果指定的属性不存在,则返回 null 或 "" (空字符串)
var attribute = element.getAttribute(attributeName);
- attribute 是一个包含 attributeName 属性值的字符串。
- attributeName 是你想要获取的属性值的属性名称。