DOM 操作
DOM(Document Object Model,文档对象模型)定义了访问和操作 HTML 文档的标准方法。DOM 以树形结构表达 HTML 文档,页面中每一个标签、文本、属性都是树上的一个节点。

获取元素
| 方法 | 说明 |
|---|---|
document.getElementById("id") | 通过 ID 获取元素,ID 重复时只返回第一个,不存在则返回 null |
document.getElementsByClassName("class") | 通过类名获取元素集合(HTMLCollection),可通过下标访问 |
document.getElementsByTagName("tag") | 通过标签名获取元素集合,用法同上 |
document.getElementsByName("name") | 通过 name 属性获取元素,常用于获取同名表单元素 |
document.querySelector("CSS选择器") | 通过 CSS 选择器获取第一个匹配的元素 |
document.querySelectorAll("CSS选择器") | 通过 CSS 选择器获取所有匹配元素的集合(NodeList) |
document.documentElement | 获取 <html> 根标签 |
document.body | 获取 <body> 标签 |
var byId = document.getElementById("myId");
var byClass = document.getElementsByClassName("myClass")[0];
var byTag = document.getElementsByTagName("div")[0];
var byName = document.getElementsByName("username")[0];
var first = document.querySelector(".myClass");
var all = document.querySelectorAll("#myId");
var html = document.documentElement;
var body = document.body;
注意:
getElementsByClassName和getElementsByTagName返回的是动态集合,页面 DOM 变化后集合会自动更新;而querySelector/querySelectorAll返回的是静态快照,不会随 DOM 变化而更新。
获取节点
获取子节点
父节点.children— 返回子元素集合(HTMLCollection),不包含文本节点和注释节点。
<div>
<p></p>
<p></p>
<p></p>
</div>
<script>
var div = document.querySelector("div");
console.log(div.children); // HTMLCollection(3) [p, p, p]
</script>

父节点.childNodes— 返回所有子节点(NodeList),包含文本节点(空白、换行)和注释节点。
<div>
<p></p>
<p></p>
<p></p>
</div>
<script>
var div = document.querySelector("div");
console.log(div.childNodes); // NodeList(7) [text, p, text, p, text, p, text]
</script>

获取父节点
元素.parentNode— 获取文档树中的直接父节点。元素.offsetParent— 获取当前元素最近的有定位(position非static)的祖先元素。
<div class="parent">
<div class="son"></div>
</div>
<script>
var son = document.querySelector(".son");
console.log(son.parentNode); // div.parent
console.log(son.offsetParent); // div.parent(若 parent 有定位)
</script>

获取兄弟及首尾节点
元素.firstElementChild— 获取第一个子元素节点(IE8 及以下用firstChild,但会包含文本节点)元素.nextElementSibling— 获取下一个兄弟元素节点(IE8 及以下用nextSibling)元素.previousElementSibling— 获取上一个兄弟元素节点(IE8 及以下用previousSibling)
<div class="parent">
<div class="son1"></div>
<div class="son2"></div>
<div class="son3"></div>
</div>
<script>
var parent = document.querySelector(".parent");
var son2 = document.getElementsByClassName("son2")[0];
console.log(parent.firstElementChild); // div.son1
console.log(son2.nextElementSibling); // div.son3
console.log(son2.previousElementSibling); // div.son1
</script>

获取节点信息
节点.nodeName— 获取节点名称(元素节点返回大写标签名,文本节点返回"#text")节点.nodeValue— 获取文本节点的内容(元素节点该属性为null)节点.nodeType— 获取节点类型(元素节点=1,属性节点=2,文本节点=3)
<div class="parent">hello world</div>
<script>
var parent = document.querySelector(".parent");
console.log(parent.nodeName); // "DIV"
console.log(parent.childNodes[0].nodeValue); // "hello world"
console.log(parent.nodeType); // 1
</script>

操作节点
创建节点
document.createElement("标签名")— 创建一个新的元素节点document.createTextNode("文本")— 创建一个新的文本节点
添加节点
父元素.appendChild(节点)— 将节点追加到父元素的末尾父元素.insertBefore(新节点, 参考节点)— 将新节点插入到参考节点之前
<div class="demo">
<p class="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
var demo = document.getElementsByClassName("demo")[0];
var p2 = document.getElementsByClassName("p2")[0];
// 创建节点并添加文本
var p3 = document.createElement("p");
var text = document.createTextNode("p3");
p3.appendChild(text);
// 在 p2 之前插入 p3
demo.insertBefore(p3, p2);
console.log(demo);
</script>

删除节点
父元素.removeChild(目标节点) — 从父元素中移除指定子节点
<div class="demo">
<p class="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
var demo = document.getElementsByClassName("demo")[0];
var p2 = document.getElementsByClassName("p2")[0];
demo.removeChild(p2);
console.log(demo);
</script>

替换节点
父元素.replaceChild(新节点, 被替换节点) — 用新节点替换指定的子节点
<div class="demo">
<p class="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
var demo = document.getElementsByClassName("demo")[0];
var p2 = document.getElementsByClassName("p2")[0];
var p3 = document.createElement('p');
p3.innerText = "p3";
demo.replaceChild(p3, p2);
console.log(demo);
</script>

复制节点
节点.cloneNode(deep) — 复制节点并返回副本,参数为 true 时深度复制(含子节点),false 时只复制节点本身
<div class="demo">div1</div>
<script>
var demo = document.getElementsByClassName("demo")[0];
var copy = demo.cloneNode(true);
console.log(copy); // <div class="demo">div1</div>
</script>
