10. DOM

10.1 节点层次

1. Node

  • DOM1 定义了一个Node 接口
  • 在JavaScript中是作为Node类型实现的
  • JavaScript中所有节点类型都继承自Node类型
Node常量 描述
ELEMENT_NODE 1 元素
TEXT_NODE 3 文本
PROCESSING_INSTRUCTION_NODE 7 处理指令
COMMENT_NODE 8 注释
DOCUMENT_NODE 9 文档
DOCUMENT_TYPE_NODE 10 文档类型
DOCUMENT_FRAGMENT_NODE 11 文档片段
ATTRIBUTE_NODE 2 属性
CDATA_SECTION_NODE 4 Unparsed Character Data 不经XML解析器进行解析的文本数据
ENTITY_REFERENCE_NODE 5 实体引用
ENTITY_NODE 6 实体
NOTATION_NODE 12
  • 属性
    • nodeType
      • Node类型中由12个数值常量,任何节点类型必居其一
      • DOM4中废弃了2、4、5、6、12
    • nodeNamenodeValue
      • 元素节点,nodeName都是标签名, nodeValue都是null
    • childNodes
      • 每个节点都有一个childNodes,里面保存着NodeList类数组对象
      • NodeList是基于DOM结构动态执行查询的结果
      • DOM结构的变化能自动反映在NodeList对象中
      • 是有呼吸有生命的对象,而不是我们第一次访问他们的某个瞬间的快照
      • 访问NodeList中的节点,可以通过方括号,也可以使用item()
      • Array.prototype.slice.call(类数组) 可以转换为数组
    • parentNode
      • firstChild
      • lastChild
    • nextSibling
      • 最后一个节点的nextSibling == null
    • previousSibling
      • 第一个节点的previousSibling == null
    • ownerDocument
      • 指向整个文档的文档节点document
// Array.prototype.slice 在 IE8 之前不支持
function convertToArray(arrayLike){
	var array = [];
	try{
		array = Array.prototype.slice.call(arrayLike);
	} catch(ex){
		for(let i = 0; i < arrayLike.length; i++){
			array.push(arrayLike[i]);
		}
	}
	return array;
}
  • 方法
    • hasChildNodes()
    • appendChild()
      • 传入原文档中不存在的节点,向childNodes列表的末尾添加一个节点
      • 传入已存在的节点,会将其从原来位置转移到新位置
    • insertBefore(newNode, existNode)
    • replaceChild(newNode, existNode)
    • removeChild()
    • cloneNode(boolean) 是否深复制
      • 只复制特性、子节点
      • 不会复制添加到DOM中的JavaScript属性,例如事件处理程序
    • normalize()
      • 可能会有文本节点不包含文本
      • 可能会接连出现两个文本节点
      • normalize()处理文档树中的文本节点

2. Document

  • 在浏览器中,document对象是HTMLDocument的一个实例,表示整个HTML页面
  • document对象是window对象的一个属性,可以作为全局变量访问
  • Document节点具有下列特征
    • nodeType == 9
    • nodeName == "#document"
    • nodeValue == null
    • parentNode == null
    • ownerDocument == null
    • 其子节点可能是一个DocumentType/Element/ProcessingInstruction/Comment
  • 文档子节点
    • documentElement 指向 <html>元素
    • body 指向 <body>元素
    • doctyoe
  • 文档信息
    • title —> <title>
    • URL
    • domain
      • 修改domain一致,来通信
      • loose 和 tight
    • referrer 连接到当前页面的那个页面的URL
  • 查找元素
    • document.getElementById()
    • document.getElementsByTagName()
      • HTMLCollection 与NodeList类似,namedItem()
    • getElementsByName() 只有HTMLDocument类型才有
  • 特殊集合
    • 特殊集合都是HTMLCollection对象
    • document.anchors 所有带name<a>
    • document.applets 所有<applet>
    • document.forms 所有<form>
    • document.images 所有<img>
    • document.links 所有带href<a>
  • DOM一致性检测
    • document.implementation
    • write()/writeln()/open()/close()

3. Element

  • Element节点具有以下特征:
    • nodeType == 1
    • nodeName == 元素标签名 == tagName
    • nodeValue == null
    • parentNode == DocumentElement
    • 其子节点可能是Element/Text/Comment/ProcessingInstuction/CDATASection/EntityRenference
  • tagName 返回元素的标签名 —> 在HTML中标签名始终全部大写,"DIV"
  • HTML元素
    • HTMLElement 标准特性
      • id 唯一标识
      • title 附加说明,工具提示条显示
      • lang 语言
      • dir 文字方向
      • className 类名
  • 操作特性
    • getAttribute() 得到自定义特性的值
    • setAttribute()
    • removeAttribute()
    • on-xxx 事件处理程序
  • attributes
    • Element类型是使用attributes属性的唯一一个DOM节点类型
  • 创建元素
    • createElement(tagName)

4. Text

  • Text节点具有以下特征:
    • nodeType == 3
    • nodeName == #text
    • nodeValue == data 文本
    • parentNode 是一个Element
    • 不支持子节点
    • appendData(text)
    • deleteData(offset, count)
    • insertData(offset, text)
    • replaceData(offset, count, text)
    • splitText(offset)
    • substringData(offset, count)
  • 创建文本节点
    • createTextNode()
  • 规范化文本节点
    • normalize()
  • 分割文本节点
    • splitText()

5. Comment

  • Comment节点类型:
    • nodeType == 8
    • nodeName == "#comment"
    • nodeValue == 注释的内容
    • parentNode == Document/Element
    • 不支持子节点

6. CDATASection

  • 只出现在XML文档

7. DocumentType

  • name —> <!DOCTYPE之后的文本
  • entities
  • notations

8. DocumentFragement

  • 文档片段,是一种轻量级文档,可以包含和控制节点,但不会像完整的文档那样占用额外的资源

9. Attr

  • name
  • value
  • specified

10.2 DOM操作技术

1. 动态脚本

  • 动态添加<script>
// 动态加载外部脚本
function loadScript(url){
	var script = document.createElement("script");
	script.type = "text/javascript";
	script.src = url;
	document.body.appendChild(script);
}
// 动态加载字符串代码
var scrip = document.createElement("script");
script.type = "text/javascript";
var text = document.createTextNode(
	"function hello(){ console.log('hello world')}"
);
script.appendChild(text);
document.body.appendChild(script);

2. 动态样式

  • <link rel="stylesheet" type="text/css" href="styles.css">
  • 必须是head标签中
// link
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = "xxx.css";
var head = document.getElementsByTagName("head")[0];
head.appendChild(link);
// style
var style = document.createElement("style");
style.type = "text/css";
var text = document.createTextNode("body{background-color: red}");
style.appendChild(text);
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);

3. 操作表格

  • insertRow
  • insertCell
  • rows
  • cells
var table = document.createElement("table");
table.border = 1;
table.width = "100%";
var tbody = document.createElement("tbody");
table.appendChild(tbody);
tbody.insertRow(0);
tbody.rows[0].insertCell(0);
tbody.rows[0].cells[0].appendChild(document.createTextNode("cell(1,1)"));
tbody.rows[0].insertCell(1);
tbody.rows[0].cells[1].appendChild(document.createTextNode("cell(1,2)"));

4. NodeList

  • 三个关键DOM集合: NodeList/NamedNodeMap/HTMLCollection

10.3 小结

  • DOM是语言中立的API,用于访问HTML和XML文档
  • DOM由各种节点构成,最基本的是Node类型,
  • 常用的有Document、Element、TextNode
  • 另外还有Comment、doctype、CDATASection和Documentfragment