JavaScript的三个组成部分:核心(ECMAScript欧洲计算机制造商协会,描述了JS的语法和基本对象),文档对象模型(DOM,把整个HTML当成一个对象,处理网页内容的方法和接口),浏览器对象模型(BOM,把浏览器当成一个对象,与浏览器交互的方法和接口)
什么是DOM和节点
DOM(文档对象模型)
DOM为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。其实就是为了能让js操作html元素而制定的一个规范。
DOM树状的树形结构

节点
由上面的结构图可以看出,整个文档就是一个文档节点,每个HTML标签都是一个元素节点,标签中的文字则是文本节点,标签的属性是属性节点,一切都是节点...
获取节点
直接获取
有三种方法:
通过id: document.getElementById('box')
返回值是一个元素节点,可以直接使用(例如获得属性值,设置属性等)。如果查找不到对应id名的节点,返回值为null而不是undefined。
通过标签名: document.getElementsByTagName('div')
通过类名: document.getElementsByClassName('box') (在IE5,6,7,8中不兼容)
通过标签名和类名获得的返回值是一个伪数组,习惯性是惯例之后再使用。查找不到对应的节点,返回值为空数组。获取其中第一个元素,是 document.getElementsByTagName('div')[0]
通过访问关系获取
节点的访问关系,是以属性的方式存在的。
节点并不是孤立的,因此可以通过DOM节点之间的相对关系对它们进行访问。
| 父节点 | 兄弟节点 | 子节点 | 所有子节点 |
| parentNode | nextSibling | firstChild | childNodes |
| nextElementSibling | firstElementChild | children | |
| previousSibling | lastChild | ||
| previousElementSibling | lastElementChild |
(1)父节点
parentNode
(2)兄弟节点
nextSibling:调用者是节点。IE678中指下一个元素节点(标签),火狐谷歌IE9+以后都指下一个节点(包括空文档和换行节点)。所以在IE678中用nextSlibling,在火狐谷歌IE9+中用nextElementSibling。
下一个兄弟节点 = 节点.nextElementSibling || 节点.nextSibling
previousSibling:指上一个兄弟节点。同nextSibling兼容相同
上一个兄弟节点 = 节点.previousElementSibling || 节点.previousSibling
(3)单个子节点
firstChild:调用者是父节点。IE678指第一个子元素节点(标签),火狐谷歌IE9+以后都指的是第一个节点(包括空文档和换行节点)。firstElementChild在火狐谷歌IE9+指第一个元素节点。
第一个子节点 = 节点.firstElementChild || 节点.firstChild
lastChild:最后一个子节点。与firstChild兼容性相同。
最后一个子节点 = 节点.lastElementChild || 节点.lastChild
(3)所有子节点
childNodes:返回指定元素的子节点集合,包含所有节点。
children:返回指定元素的子节点集合,只包含元素节点。它是非标准属性,在IE678中,包含注释节点。
节点操作
创建节点
document.createElement()
插入节点
父节点.appendChild()
<div id="box"></div>
<script>
//创建节点li
var liNode = document.createElement('li');
//获取父元素
var box = document.getElementById('box');
//添加
box.appendChild(liNode);
</script>
父节点.insertBefore()
<div id="box">
<span></span>
<span id="span"></span>
<span></span>
</div>
<script>
//创建节点li
var liNode = document.createElement('li');
//获取父元素
var box = document.getElementById('box');
var span = document.getElementById('span');
//将新创建的节点添加到#span前
box.insertBefore(liNode, span);
</script>
删除节点
父节点.removeChild()
<div id="box">
<span></span>
<span id="span"></span>
<span></span>
</div>
<script>//获取父元素
var box = document.getElementById('box');
var span = document.getElementById('span');
//删除#span节点
box.removeChild(span);
</script>
或者可以只查找自己本身来删除本身
<script>
//获取自身元素
var span = document.getElementById('span');
//删除#span节点
span.parentNode.removeChild(span);
</script>
复制节点
oldNode.cloneNode(true)。
接受一个布尔值参数,true表示深复制(复制节点及其所有子节点),false表示浅复制(复制节点本身,不复制子节点)。谁调用复制谁。
属性操作
通过元素.属性名或者元素[属性名]
<img src="./1.png" alt="图片" title="图片1" id="img1" class="image">
<script>
var img = document.getElementById('img1');
console.log(img.src);
console.log(img['src']);
console.log(img.className);
console.log(img['className']);
</script>
通过getAttribute,setAttribute和removeAttribute操作
<img src="./1.png" alt="图片" title="图片1" id="img1" class="image">
<script>
var img = document.getElementById('img1');
//获取
console.log(img.getAttribute('id'));
//设置
img.setAttribute('id', 'img2');
//删除
img.removeAttribute('alt');
</script>
这两个方法的区别是,前者操作的是DOM对象本身,后者操作的是标签本身。例如通过点方法添加一个'aaa'属性,就不能在html中展示出来,但是能获取到。通过setAttribute方法添加,就会在html结构中展示出来并能获取到。