1. DOM:Document Object Model文档对象模型
DOM是网页的编程接口。是针对XML但经过扩展用于HTML的应用程序编程接口。DOM将整个页面映射成一个多节点结构。
2. 节点层级
2.1. 节点
DOM的最小组成单位。
常用节点:
- 文档节点(document)
document对象最为window对象的属性,根节点,不用获取,可以直接使用。 - 元素节点(Element)
HTML文档中的HTML标签。根元素节点只有<html>
一个。 - 属性节点(Attribute)
属性节点是元素节点的一部分,不是子节点。上图中,href为a标签的属性节点。 - 文本节点(Text)
HTML标签中的文本内容。
其他节点:
- DocumentType
doctype标签(如<!DOCTYPE html>
)。 - Comment
注释 - DocumentFragment
文档的片段
2.2. 节点树
最顶层节点为document
节点,代表整个文档。文档里最高的HTML标签一般为<html>
,构成树结构的根节点,其他HTML标签节点都是它的下级。
DOM提供操作接口,用于获取三种关系的节点:
- 子节点接口,包括
firstChild
(第一个子节点)、lastChild
(最后一个子节点)等属性 - 同级接口,包括
nextSibling
(紧邻在后的那个同级节点)、previousSibling
(紧邻在前的那个同级节点)属性
3. Node类型
这个接口是所有DOM节点类型都必须实现的。Node接口在JavaScript中被实现为Node类型,在除IE之外的浏览器中都可以直接访问这个类型。在JavaScript中,所有节点类型都继承Node类型,因此所有类型都共享相同的基本属性和方法。
3.1. 属性
3.1.1. nodeType
nodeType属性返回一个整数值,表示节点类型,常用节点类型如下:
节点类型 | 值 | 对应常量 |
---|---|---|
文档节点(document) | 9 | Node.DOCUMENT_NODE |
元素节点(Element) | 1 | Node.ELEMENT_NODE |
属性节点(Attribute) | 2 | Node.ATTRIBUTE_NODE |
文本节点(Text) | 3 | Node.TEXT_NODE |
文档类型节点(DocumentType) | 10 | Node.DOCUMENT_TYPE_NODE |
注释节点(Comment) | 8 | Node.COMMENT_NODE |
文档片段节点 | 11 | Node.DOCUMENT_FRAGMENT_NODE |
<script>
console.log(document.body.nodeType);//1
</script>
3.1.2. nodeName
nodeName属性返回节点的名称
<script>
console.log(document.body.nodeName);//BODY
</script>
3.1.3. nodeValue
nodeValues属性返回一个字符串,表示当前节点本身的文本值
<div id="d1">hello world</div>
<script>
var div = document.getElementById('d1');
console.log(div.nodeValue);//null
//读
console.log(div.firstChild.nodeValue);//hello world
//写
div.firstChild.nodeValue='123';
console.log(div.firstChild.nodeValue);//123
</script>
3.1.4. textComtent
textComtent属性返回当前节点和它的所有后代节点的文本内容
<div id="d1">Hello <span>JavaScript</span> DOM</div>
<script>
var div = document.getElementById('d1');
console.log(div.textContent);//Hello JavaScript DOM
</script>
3.1.5. nextSibling
nextSiling属性返回紧跟在当前节点后面的第一个同级节点。如果当前节点后面没有同级节点,则返回null(可能会获得“空格”或“回车”这样的节点)
<div id="d1">hello</div><div id="d2">world</div>
<script>
var div1 = document.getElementById('d1');
var div2 = document.getElementById('d2');
console.log(div1.nextSibling);//<div id="d2">world</div>
console.log(div1.nextSibling === d2);//true
</script>
3.1.6. previousSibling
previousSibling属性返回当前节点前面的、距离最近的一个同级节点。如果当前节点前面没有同级节点,则返回null
<div id="d1">hello</div><div id="d2">world</div>
<script>
var div1 = document.getElementById('d1');
var div2 = document.getElementById('d2');
console.log(div2.previousSibling);//<div id="d1">hello</div>
console.log(div2.previousSibling === d1);//true
</script>
3.1.7. parentNode
parentNode属性返回当前节点的父节点。一个节点的父节点只可能是三种类型:元素节点、文档节点、文档片段节点
<div id="d1">hello</div><div id="d2">world</div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.parentNode);//<body>
</script>
3.1.8. parentElement
parentElement属性返回当前节点的父元素节点。如果当前节点没有父元素节点,或者父节点不是元素节点,返回null
<div id="d1">hello</div><div id="d2">world</div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.parentElement);//<body>
</script>
3.1.9. firstChild和lastChild
firstChild属性返回当前节点的第一个子节点,没有则返回nulll;lastChild返回最后一个子节点
<div id="d1">hello world<div>我是子节点</div></div>
<div id="d2"><div>我是子节点</div></div>
<script>
var div1 = document.getElementById('d1');
var div2 = document.getElementById('d2');
console.log(div1.firstChild);//#text "hello world"
console.log(div1.lastChild);//<div>我是子节点</div>
</script>
3.1.10. childNodes
childNodes属性返回一个类似数组的对象(Nodelist集合),成员包括当前节点的所有子节点
<div id="d1">hello world<div>我是子节点</div></div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.childNodes);//NodeList [ #text, div ]
</script>
3.2. 方法
以下方法为常用操作节点的方法,且都需要父节点对象进行调用
3.2.1. appendChild()
接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点。返回值为插入文档的子节点。
//创建节点
var p = document.createElement('p');
//向p标签插入内容
p.innerHTML = '我是一个p标签';
//将节点插入到body中
document.body.appendChild(p);
3.2.2. insertBefore()
将某个节点插入父节点内部的指定位置
<div id="parentElement">
<span id="childELement">foo bar</span>
</div>
<script>
//创建节点
var sp1 = document.createElement('span');
//向sapn标签插入内容
sp1.append('我是span标签');
var sp2 = document.getElementById('childELement');
//获取父节点的引用
var parentDiv = sp2.parentNode;
//将sp1节点插入到sp2节点之前
parentDiv.insertBefore(sp1, sp2);
</script>
3.2.3. removeChild
接受一个子节点作为参数,用于从当前节点移除该子节点,并返回移除的节点
<div id="d1">
<span id="s1">我是span标签</span>
</div>
<script>
var span1 = document.getElementById('s1');
var res = span1.parentNode.removeChild(span1);
console.log(res)//<span id="s1">我是span标签</span>
</script>
3.2.4. replaceChild
将一个新的节点替换当前节点的某一个节点
<div id="d1">
<span id="s1">我是span标签</span>
</div>
<script>
var span1 = document.getElementById('s1');
var div1 = document.createElement('div');
div1.innerHTML = '我是新建的div元素';
span1.parentNode.replaceChild(div1, span1);
</script>
4. Document类型
JavaScript通过使用Document类型表示文档。在浏览器中,document对象表示整个HTML文档,document对象时HTMLDocument的一个实例。document对象是window对象的一个属性,可以直接调用。HTMLDocument继承自Document类型。
4.1. 属性
- documentElement:始终指向HTML页面中的
<html>
元素 - body:直接指向
<body>
元素 - doctype:访问
<!DOCTYPE>
,浏览器支持不一致,很少使用 - title:获取文档的标题
- URL:取得完整的URL
- domain:取得域名,并且可以进行设置。在跨域访问中经常用到。
- referrer:取得链接到当前页面的那个页面的URL,即来源页面的URL。
- images:获取所有的img对象,返回HTMLCollection类数组对象。
- forms:获取所有的form对象,返回HTMLCollection类数组对象。
- links:获取文档中所有href属性的
<a>
元素
4.2. DOM编程界面
HTML DOM能够通过JavaScript进行访问
在DOM中,所有HTML元素都被定义为对象。
编程界面是每个对象的属性和方法。属性是能够获取或设置的值(如改变HTML元素的内容),方法是能够完成的动作(如添加或删除HTML元素)
<p id="demo"></p>
<script>
document.getElementById('demo').innerHTML = "Hello World!";
</script>
其中,getElementById()是方法,innerHTML是属性。
innerHTML属性:
获取元素内容最简单的方法是使用innerHTML属性。该属性用于获取或替换HTML元素的内容,包括<html>
和<body>
。
4.2.1. 查找元素
4.2.1.1. getElementById()
返回匹配指定id的一个元素
4.2.1.2. getElementByTagName()
返回一个HTMLCollection
(伪数组),包含匹配指定标签名的所有元素
4.2.1.3. getElementByClassName()
返回一个HTML集合HTMLCollection
(伪数组),包含匹配指定类名的所有元素
4.2.1.4. querySelector()
返回文档中匹配指定的CSS选择器的第一元素
<p id="demo">1</p>
<P id="demo">2</P>
<script>
document.querySelector('#demo').innerHTML = "Hello World!";
</script>
4.2.1.5. querySelectorAll()
HTML5新引入的方法,返回文档中匹配的CSS选择器的所有元素节点列表
<p id="demo">1</p>
<P id="demo">2</P>
<script>
console.log(document.querySelectorAll('#demo'));
var x = document.querySelectorAll('#demo');
x[0].innerHTML = '我是新的div'
</script>
4.2.2. 添加元素
createElement()
创建一个新的HTML元素,一般与appendChild()]或insertBefore()连用
//创建节点
var p = document.createElement('p');
//向p标签插入内容
p.innerHTML = '我是一个p标签';
//将节点插入到body中
document.body.appendChild(p);
4.2.3. 写入
write()
向文档写入文本或HTML表达式或JavaScript代码(使用JS写入时,块级元素以及行内元素特性存在)
<!-- hello world -->
<!-- hello worldchina -->
<script>
document.write('<p>hello world</p>');
document.write('<span>hello world</span>');
document.write('china');
5. Element类型
Element对象对应网页的HTML元素。每一个HTML元素在DOM树上都会转化成一个Element节点对象
5.1. 属性
- attributes:返回一个与该元素相关的所有属性的集合
- classList:返回该元素包含的class属性的集合
- className:获取或设置指定元素的class 属性的值
- clientHeight:获取元素内部的高度,包含内边距,但不包括水平滚动条、边框和外边距
- clientTop:返回该元素距离它上边界的高度
- clientLeft:返回该元素距离它左边界的宽度
- clientWidth:返回该元素它内部的宽度,包括内边距,但不包括垂直滚动条、边框和外边距
- innerHTML:设置或获取HTML语法表示的元素的后代
- tagName:返回当前元素的标签名
5.2. 常用方法
- element.innerHTML = new html content
改变元素的innerHTML - element.attribute = value
修改属性的值(针对内置属性值)
<div id="div1">我是一个div</div>
<script>
var d1 = document.getElementById('div1');
d1.id = 'div2'
</script>
- element.getAttribute()
返回元素节点的指定属性值
<div id="div1" class="class1">我是一个div</div>
<script>
var d1 = document.getElementById('div1');
console.log(d1.getAttribute('class'));
</script>
- element.setAttribute(attribute, value)
设置或改变HTML元素的属性(针对自定义属性值)
<div id="div1">我是一个div</div>
<script>
var d1 = document.getElementById('div1');
d1.setAttribute('class', 'divCla');
</script>
- element.style.property = new style
改变HTML元素的样式
<div id="div1">我是一个div</div>
<script>
var d1 = document.getElementById('div1');
console.log(d1.style);
d1.style.backgroundColor = 'red';
</script>
6. Text类型
Text节点由Text类型表示,包含按字面解释的纯文本,也可能包含转义后的HTML字符,但不含HTML代码
6.1. 属性及方法
- length:文本长度
- appendData(text):追加文本
- deleteData(beginIndex, count):删除文本
- insertData(beginIndex, text):插入文本
- replaceData(beginIndex, count, text):替换文本
- splitText(beginIndex):从beginIndex位置将当前文本节点分成两个文本节点
- document.createTextNode(text):创建文本节点,参数为要插入节点中的文本
- substringData(beginIndex, count):从beginIndex开始提取count个子字符串