JavaScript快速入门笔记(10):文档对象模型(DOM)及 document 对象
本系列随笔是本人的学习笔记,初学阶段难免会有理解不当之处,错误之处恳请指正。转载请注明出处:https://www.cnblogs.com/itwhite/p/12248730.html。
简介
文档对象模型(Document Object Model)简称 DOM ,它提供了一套用于表示和操作 HTML 和 XML 文档内容的接口(API)。
DOM 描绘了一个层次化的节点树,允许开发人员通过添加节点、删除节点或修改该节点来更新文档页面内容。
比如下面一个 HTML 文档:
<html> <head> <title>Sample Document</title> </head> <body> <h1>An HTML Document</h1> <p>This is a <i>simple</i> document. </body> </html>
将生成如下图所示的 DOM 节点树:
上图中每一个方框表示一个节点,其中包含三类节点:Document(根节点)、Element(使用尖括号括起来的节点) 和 Text(使用双引号括起来的节点)。
节点类型继承关系
从前面的示例中看到,DOM 树中的节点内容不同,类型也会有差异,比如:根节点是 Document 类型节点,标签元素是 Element 类型节点,文本内容是 Text 类型节点。
各个大类型还派生出了各自的具体子类型,例如 HTML 元素就有很多种具体类型,这些类型继承关系如下图所示:
由于 DOM 不仅是针对 HTML 而设计的,还可以应用于 XML,Document 和 Element 的子类中包含以 HTML 为命名前缀的子类型,表示针对 HTML 设计的子类(针对 XML 的上图中并未列出)。
鉴于 HTML 中各个标签元素的差异,HTMLElement 类型也有很多代表 HTML 元素的具体子类型。将这些子类型标记到前面的 DOM 树中,如下图所示:
Node 类型
从节点类型关系图来看,Node 是所有其它类型的父类型,其它类型会继承它的属性和方法。
通过 Node 类型的属性和方法,我们可以遍历整个节点树(根节点为 document 对象),也可以修改某个节点(比如:添加、删除子节点)。不过节点的创建需要使用 Document 类型的方法,例如:document.createElement("p")。
Node 类型中常用属性和方法:
属性/方法 | 描述 |
nodeType | 一个数字值,表示节点类型,1表示Element节点,3表示Text节点,8表示Comment节点,9表示Document节点 |
nodeName | 如果是Element节点的话,该属性值就是元素的标签名(大写),如:P、DIV 等 |
nodeValue | Text节点或Comment节点的文本内容,其它节点的话,此属性为null |
parentNode | 当前节点的父节点(如果当前节点是Document节点的话,则为null,因为Document节点没有父节点) |
childNodes | NodeList类型,当前节点的子节点列表 |
firstChild | 第一个子节点,如果没有则为null |
lastChild | 最后一个子节点,如果没有则为null |
nextSibling | 下一个兄弟节点(与当前节点有相同的父节点) |
previousSibling | 前一个兄弟节点(与当前节点有相同的父节点) |
children | HTMLCollection类型,当前节点的Element子节点集合(其中只包含Element节点,注意与childNodes的区别) |
appendChild() | 在当前节点末尾追加一个子节点 |
insertBefore() | 在当前节点前面插入一个兄弟节点,示例:parentNode.insertBefore(newNode, currentNode) |
removeChild() | 删除当前节点的一个子节点,示例:currentNode.removeChild(child) |
replaceChild() | 替换当前节点的一个子节点,示例:parentNode.replaceChild(newChild, oldChild) |
关于 Node 类型更多的属性和方法请参考:https://developer.mozilla.org/en-US/docs/Web/API/Node。
关于 nodeType 和 nodeValue 的参考示例:
<p id="demo">Hi, I'm <span style="color:green">P</span> element</p> <script> var p = document.getElementById('demo'); var c0 = p.childNodes[0]; var c1 = p.childNodes[1]; var c2 = p.childNodes[2]; console.log(c0.nodeType, c0.nodeValue); // 3 Hi, I'm console.log(c1.nodeType, c1.nodeValue); // 1 null console.log(c1.childNodes[0].nodeType, c1.childNodes[0].nodeValue); // 3 P console.log(c2.nodeType, c2.nodeValue); // 3 element </script>
Document 类型:document 对象
Document 节点是 DOM 节点树的根节点,通过它我们可以遍历到任意子节点,因此可以通过它来操控整个节点树。
window 对象的 document 属性正好指向该节点,因为 document 是 window 对象的属性,因此我们也可以把它当做全局变量来使用。
document 是 HTMLDocument 类型的一个实例,它继承了 Document 类型的属性和方法(同时,Document 继承自 Node,因此 Node 类型的属性和方法也可以用于 document),常用属性和方法如下表所示:
属性 | 描述 |
---|---|
documentElement | 存放 <html> 元素节点对象(HTMLHtmlElement类型) |
head | 存放 <head> 元素节点对象(HTMLHeadElement类型) |
body | 存放 <body> 元素节点对象(HTMLBodyElement类型) |
title | 存放 <title> 元素节点文本(String) |
URL | 存放 文档页面 URL (String) |
forms | 存放所有 <form> 元素节点对象的集合(HTMLCollection类型) |
images | 存放所有 <img> 元素节点对象的集合(HTMLCollection类型) |
getElementById() | 根据元素 id 属性获取元素节点对象,例如:document.getElementById("foo") |
getElementsByName() | 根据元素 name 属性获取元素节点对象集合(返回HTMLCollection类型),例如:document.getElementsByName("bar") |
getElementsByTagName() | 根据元素标签名获取元素节点对象集合(返回HTMLCollection类型),例如:document.getElementsByTagName("p") |
getElementsByClassName() | 根据元素 class 属性获取元素节点对象集合(返回HTMLCollection类型),例如:document.getElementsByClassName("qux") |
createElement() | 创建Element节点,例如:var p = document.createElement("p"); p.innerHTML = "This is a <b>paragraph</b>"; |
createTextNode() | 创建Text节点,例如:var text = document.createTextNode("another text"); p.appendChild(text); |
更多的属性和方法请参考:https://developer.mozilla.org/en-US/docs/Web/API/Document。
Element 类型:HTML 元素的属性和方法
从上面的节点类型关系图中可以看到, HTML 元素都有各自的具体类型(少数除外),他们都继承自 HTMLElement ,HTMLElement 又继承自 Element,Element 继承自 Node (HTMLElement => Element => Node) 。
因此 Node 、Element、HTMLElement 的所有属性和方法都可以应用于 HTML 元素节点对象, 另外各个 HTML 元素具体类型也有各自特有的属性和方法。
Element、HTMLElement 中定义了一些通用的属性和方法,其中常用属性和方法如下:
属性/方法 | 描述 |
id | 元素的 id 属性值 |
title | 元素的 title 属性值 |
style | 元素的 style 属性对象,它本身也包含很多属性,例如:width、backgroundColor等 |
className | 元素的 class 属性值 |
innerHTML |
元素的HTML内容,比如:<p>This is a <b>paragraph</b></p>中<p>元素的 innerHTML 为:This is a <b>paragraph</b> 注:Node 类型有个属性 textContent,它在此例子中值为 This is a paragraph (去掉了标签外壳) |
getAttribute() | 获取元素的某个属性值,例如:var align = div.getAttribute("align"); |
setAttribute() | 设置元素的某个属性值,例如:div.setAttribute("id", "demo"); |
hasAttribute() | 判断元素是否设置了某个属性 |
getElementsByTagName() | 与 document 的同名方法一样,根据标签名获取元素集合(从当前元素的子元素中查找,递归向下) |
getElementsByClassName() | 与 document 的同名方法一样,根据元素 class 属性获取元素集合(从当前元素的子元素中查找,递归向下) |
各个 HTML 元素具体类型也有各自特有的属性和方法,例如:<img> 元素有 src 属性,<a> 元素有 href 属性等,大部分情况下,我们都可以直接根据属性名进行访问,例如:
<img id="imgdemo" src="1.jpg" /> <a id="anchordemo" href="page-2.html" >Next</a> <script> var img = document.getElementById("imgdemo"); img.src = "2.jpg"; var a = document.getElementById("anchordemo"); a.href = "page-3.html"; </script>
HTML 元素具体类型中的属性的一般命名规则如下:
- 若 HTML 属性名中包含多个单词,相应元素节点属性中除首字母以外的单词首字母都大写,例如:tabindex => tabIndex
- 若 HTML 属性名与 JavaScript 的关键字冲突,则相应属性名中添加 html 前缀,例如:<label> 标签的属性 for => htmlFor
- class 属性是个例外,不是在前面添加 html 前缀,而是 class => className
- 以上规则也同样适用于 style 属性中的子属性,例如:div.style.backgroundColor = "green"
更多的属性和方法请参考:
- https://developer.mozilla.org/en-US/docs/Web/API/Element
- https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
- https://developer.mozilla.org/en-US/docs/Web/API
完。