基本概念
文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使程序对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本语言连接起来
一个web页面是一个文档。这个文档可以在浏览器窗口或作为HTML源码显示出来。但文档对象模型(DOM)提供了对同一份文档的另一种表现:存储和操作的方式。 DOM是web页面的完全的面向对象表述,它能够使用如 JavaScript等脚本语言进行修改。
DOM并不是天生就被规范好了的,早在W3C将DOM纳入规范之前就已经产生DOM了,这些内容我们一般称之为DOM0。现在DOM的标准一直在被W3C管理着。
DOM 并不是一个编程语言,它只是一纸规范。规范可以由不同的语言来实现。由于javascript语言本身的特点。它更适合来实现DOM。但绝不是只能由javascript来实现DOM。即DOM的设计与编程语言是互相独立的。
正如W3C所定义的,DOM是独立于平台和语言的接口,该接口为程序和脚本提供了对文档的内容、结构和样式的动态获取和更新的功能。
DOM的出现来自对动态页面的需求,先有DOM的实现(Netscape DOM0),再有各个厂商对DOM实现规范的需求,再有了W3C Activity Statement对于DOM发展的规范,然后才有了我们所说的“DOM”。
DOM0:不是W3C规范。
DOM1:开始是W3C规范。专注于HTML文档和XML文档。
DOM2:对DOM1增加了样式表对象模型(DOM2)
DOM3:对DOM2增加了内容模型 (DTD 、Schemas) 和文档验证。
DOM0指的是Necscape3.0和IE3.0提供对于HTML文档功能,实现了包括元素(HTML Element)、表单(Form)、图像(Image)等的接口和方法。DOM0虽然年代久远,某些实现并不符合新的DOM理念,但为了向后兼容,很多现代浏览器仍然支持DOM0的某些方法和属性。即便某些方法的实现原理有所不同,但提供了可用性。DOM0出现后,各厂商意识到DOM的前景,纷纷向W3C建议DOM的规范化。于是出现了W3C DOM Activity Statement(DOM的活动清单)以及DOM1、DOM2、DOM3规范(Specification)
DOM实际上是由HTML元素和其他的多种类型组成的。所有组成DOM的东西被称为DOM节点。这些节点可以是元素、属性、文本内容、注释、文档相关的内容等。。
你想要访问的每个HTML元素都有一个与之相关联的特定类型,并且所有这些类型都从Node类型扩展出来的。
EventTarget:是root抽象类(Abstract Class)。该类的对象永远不会创建。它作为一个基础,因此所有的DOM节点都支持所谓的事件(Events)
Node:也是一个抽象类,作为DOM节点的基础。它提供了核心功能:parentNode、nextSibling、childNodes等)。节点类的对象没有被创建。但是,有一些具体的节点类继承了它,比如:文本节点的Text,元素节点的Element以及注释节点的Comment等
Element:是DOM元素的基本类。它提供了元素级的搜索,比如nextElementSibling、childern、getElementsByTagName、querySelector等。在浏览器中,不仅有HTML,还有XML和SVG文档。元素类是更具体类的一些基础,比如SVGElement、XMLElement和HTMLElement
HTMLElement:是HTML元素的基本类,它由各种HTML元素继承。比如HTMLInputElemnt(对应input元素的类)、HTMLBodyElement(对应body元素的类)和HTMLAnchorElement(对应a元素的类)等
根据id获取元素节点
语法:element = document.getElementById(id);
参数:id是大小写敏感的字符串,代表了所要查找的元素的唯一ID.
返回值:element是一个 Element 对象。如果当前文档中拥有特定ID的元素不存在则返回null
根据类名
语法:
var elements = document.getElementsByClassName(names);
var elements = rootElement.getElementsByClassName(names)
参数:names 是一个字符串,表示要匹配的类名列表;类名通过空格分隔
返回值:elements 是一个实时集合,包含了找到的所有元素
注意:
获取所有 class 为 'test' 的元素:document.getElementsByClassName('test');
获取所有 class 同时包括 'red' 和 'test' 的元素:document.getElementsByClassName('red test');
根据标签名
语法:
var elements = document.getElementsByTagName(name);
var elements = element.getElementsByTagName(name)
参数:name 是一个代表元素的名称的字符串。特殊字符 "*" 代表了所有元素
返回值:
elements 是一个由发现的元素出现在树中的顺序构成的HTML集合
子节点
childNodes(Node)
Node.childNodes 返回包含指定节点的子节点的集合(包含文本节点)
语法:var list= node.childNodes;
返回值:包含文本节点的子节点列表(只读)
firstChild
Node.firstChild 只读属性返回树中节点的第一个子节点,如果节点是无子节点,则返回 null。
lastChild
Node.lastChild 是一个只读属性,返回当前节点的最后一个子节点。如果没有子节点,则返回 null
children(Element 实现于 ParentNode)
ParentNode.children 返回包含指定节点的子节点的集合(剔除文本节点)
语法:
var children = node.children;
var elList = element.children;
返回值: 剔除文本节点的子节点列表(只读)
childElementCount
ParentNode.childElementCount 只读属性返回一个无符号长整型数字,表示给定元素的子元素数。
firstElementChild
ParentNode.firstElementChild 只读属性,返回对象的第一个孩子 Element, 如果没有子元素,则为null。
lastElementChild
ParentNode.lastElementChild 只读属性返回对象的最后一个孩子Element ,如果没有子元素,则返回null
获取兄弟节点
nextSibling(Node)
Node.nextSibling 是一个只读属性,返回其父节点的 childNodes 列表中紧跟在其后面的节点,如果指定的节点为最后一个节点,则返回 null
previousSibling(Node)
Node. previousSibling是一个只读属性,返回当前节点的前一个兄弟节点,没有则返回null.
nextElementSibling(Element 实现于NonDocumentTypeChildNode)
nextElementSibling 返回当前元素在其父元素的子元素节点中的后一个元素节点,如果该元素已经是最后一个元素节点,则返回null,该属性是只读的.
previousElementSibling(Element 实现于NonDocumentTypeChildNode)
previousElementSibling 返回当前元素在其父元素的子元素节点中的前一个元素节点,如果该元素已经是第一个元素节点,则返回null,该属性是只读的.
获取父节点
Node.parentNode
返回指定的节点在DOM树中的父节点
parentNode是指定节点的父节点.一个元素节点的父节点可能是一个元素(Element )节点,也可能是一个文档(Document )节点,或者是个文档碎片(DocumentFragment)节点.
对于下面的节点类型: Attr, Document, DocumentFragment, Entity, Notation,其parentNode属性返回null.
Node.parentElement
返回当前节点的父元素节点,如果该元素没有父节点,或者父节点不是一个元素节点.则 返回null.
query
querySelector
语法:element = document.querySelector(selectors);
参数:selectors包含一个或多个要匹配的选择器字符串,该字符串必须是有效的CSS选择器字符串
返回值:表示文档中与指定的一组CSS选择器匹配的第一个元素的Element对象。
querySelectorAll
语法:elementList = document.querySelectorAll(selectors);
参数:selectors 是一个或多个CSS选择器,这些选择器由逗号隔开
返回值:表示文档中与指定的一组CSS选择器匹配元素列表
属性节点
对于属性节点的获取,我们一般都是指对属性节点值的获取
Element.attributes
Element.attributes 属性返回该元素所有属性节点的一个实时集合。是字符串形式的名/值对,每一对名/值对对应一个属性节点。
Element.getAttribute(attributeName)
Element.getAttribute() 返回元素上一个指定的属性值。如果指定的属性不存在,则返回 null 或 "" (空字符串)
语法:var attribute = element.getAttribute(attributeName);
参数:attributeName 是你想要获取的属性值的属性名称
返回值:attribute 是一个包含 attributeName 属性值的字符串
Element.getAttributeNames()
Element.getAttributeNames() 返回一个Array,该数组包含指定元素(Element)的所有属性名称,如果该元素不包含任何属性,则返回一个空数组。
Element.getAttributeNode(attrName)
返回指定元素的指定属性, 返回值是 Attr 节点类型
语法:var attrNode = element.getAttributeNode(attrName);
参数:attrName 是一个包含属性名称的 字符串
返回值:attrNode 获得的属性返回值,是Attr 节点,nodeType 为 2
Element.hasAttribute(attName)
hasAttribute 返回一个布尔值,指示该元素是否包含有指定的属性(attribute)
语法:var result = element.hasAttribute(attName);
参数:attName 是一个字符串,表示属性的名称。返回值:result 为返回的布尔值:true 或false。
文本节点的获取
对于文本节点的获取,我们一般都是指对文本节点值的获取
Node.innerText
Node.innerText是一个表示一个节点及其后代的“渲染”文本内容的属性
Node.textContent
Node.textContent表示一个节点及其后代的文本内容
与innerText的区别
innerText 受 CSS 样式的影响,并且不会返回隐藏元素的文本,而textContent会。innerText会触发重排(reflow),但textContent 不会。
textContent的性能要优于innerText
Element.innerHTML
设置或获取HTML语法表示的元素的后代
新增元素节点
Document.createElement(tagName)
Document.createElement(tagName) 方法创建由tagName 指定的HTML元素节点
Node.appendChild()
Node.appendChild(child) 方法将一个节点添加到指定父节点的子节点列表末尾。
语法:var child = node.appendChild(child);
参数:child 即是参数又是这个方法的返回值.
返回值:child 即是参数又是这个方法的返回值.
元素节点插入
Node.insertBefore()
Node.insertBefore() 方法在参考节点之前插入一个节点作为一个指定父节点的子节点
语法:
var insertedElement = parentElement.insertBefore(newElement, referenceElement);
参数:
parentElement是新插入节点的父节点
newElement 是被插入的节点
referenceElement 参考节点
返回值:
insertedElement:是被插入的节点,即 newElement
Element.insertAdjacentElement()
insrtAdjacentElement() 方法将一个给定的元素节点插入到相对于被调用的元素的给定的一个位置。
语法:element.insertAdjacentElement(position, element);
参数:
position:字符串文本 表示相对于该元素的位置;必须是以下字符串之一:
'beforebegin': 在该元素本身的前面
'afterbegin':只在该元素当中, 在该元素第一个子孩子前面.
'beforeend':只在该元素当中, 在该元素最后一个子孩子后面.
'afterend': 在该元素本身的后面.
节点的替换
Node.replaceChild(newChild, oldChild);
用指定的节点替换当前节点的一个子节点,并返回被替换掉的节点
语法:
var replacedNode = parentNode.replaceChild(newChild, oldChild);
参数:newChild :
用来替换 oldChild 的新节点。如果该节点已经存在于DOM树中,则它会被从原始位置删除。
oldChild : 被替换掉的原始节点
返回值:replacedNode 和oldChild相等,即返回被替换掉的节点
节点的删除
Node.removeChild()
Node.removeChild() 方法从DOM中删除一个子节点。返回删除的节点
语法:oldChild = node.removeChild(child);
参数:
node 是child的父节点.
child 是要移除的那个子节点.
返回值:oldChild保存对删除的子节点的引用.
ChildNode.remove()
ChildNode.remove() 方法把从它所属的DOM树中删除对象
属性的增删改
document.createAttribute(name)//创建一个新的属性节点
Element.setAttribute(name, value);
Element.setAttribute设置指定元素上的一个属性值。如果属性已经存在,则更新该值; 否则将添加一个新的属性用指定的名称和值。
语法:element.setAttribute(name, value);
参数:name 是表示属性名称的字符串
value 是属性的新值
Element.setAttributeNode()
setAttributeNode() 为指定的 Element 添加属性节点
语法:var replacedAttr = element.setAttributeNode(attribute);
参数:attribute是添加到 element 中的属性节点.
返回值:被替换掉的属性节点
Element.removeAttribute()
removeAttribute() 从指定的元素中删除一个属性
语法:element.removeAttribute(attrName)
参数:attrName 是一个字符串,将要从元素中删除的属性名。
Element.removeAttributeNode(attributeNode)
removeAttributeNode 从当前的 element(元素节点) 删除指定的属性
语法:removedAttr = element.removeAttributeNode(attributeNode)
参数:attributeNode 是需要被删除的 Attr 节点。
返回值:removedAttr 是被删除了的 Attr 节点。