一、DOM是什么?
- Document Object Model
- 文档对象模型,通过DOM可以来任意修改网页中各个内容
- 文档
文档指的是网页,一个网页就是一个文档
- 对象
对象指将网页中的每一个节点都转换为对象
转换为对象后,就可以以一种纯面向对象的形式来操作网页了
- 模型
模型用来表示节点和节点之间的关系,方便操作页面
1.节点(Node)
- 节点是构成网页的最基本的单位,网页中的每一个部分都可以称为一个节点
- 每个结点的类型都是不同的
- 常用的节点
- 文档节点(Document),代表整个网页
- 元素节点(Element),代表网页中的标签
- 属性节点(Attribute),代表标签中的属性
- 文本节点(Text),代表网页中的文本内容
2.节点树
- 一个文档的所有节点,按照所在的层级,可以抽象成一种树状结构。这种树状结构就是 DOM 树。
- 它有一个顶层节点,下一层都是顶层节点的子节点,然后子节点又有自己的子节点。
- 就这样层层衍生出一个金字塔结构,倒过来就像一棵树。
二、Node接口的属性
nodeType
nodeType属性返回一个整数值,表示节点的类型。
-
不同节点的nodeType属性值和对应的常量如下。
文档节点(document):9,对应常量Node.DOCUMENT_NODE 元素节点(element):1,对应常量Node.ELEMENT_NODE 属性节点(attr):2,对应常量Node.ATTRIBUTE_NODE 文本节点(text):3,对应常量Node.TEXT_NODE 文档片断节点(DocumentFragment):11,对应常量Node.DOCUMENT_FRAGMENT_NODE 文档类型节点(DocumentType):10,对应常量Node.DOCUMENT_TYPE_NODE 注释节点(Comment):8,对应常量Node.COMMENT_NODE
console.log(document.nodeType); //9
nodeName
nodeName属性返回节点的名称。
-
不同节点的nodeName属性值如下。
文档节点(document):#document 元素节点(element):大写的标签名 属性节点(attr):属性的名称 文本节点(text):#text 文档片断节点(DocumentFragment):#document-fragment 文档类型节点(DocumentType):文档的类型 注释节点(Comment):#comment
<div id="d1">hello world</div>
<script>
var div = document.getElementById('d1');
console.log(div.nodeName); //DIV
</script>
nodeValue
nodeValue属性返回一个字符串,表示当前节点本身的文本值,该属性可读写只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值。
<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';
</script>
textContent
textContent属性返回当前节点和它的所有后代节点的文本内容。
<div id="d1">Hello <span>JavaScript</span> DOM</div>
<script>
var div = document.getElementById('d1');
console.log(div.textContent); //Hello JavaScript DOM
</script>
nextSibling
nextSibling属性返回紧跟在当前节点后面的第一个同级节点。如果当前节点后面没有同级节点,则返回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 === div2); // true
</script>
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 === div1); // true
</script>
parentNode
parentNode属性返回当前节点的父节点。对于一个节点来说,它的父节点只可能是三种类型:元素节点(element)、文档节点(document)和文档片段节点(documentfragment)。
<div id="d1">hello world</div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.parentNode); // body
</script>
parentElement
parentElement属性返回当前节点的父元素节点。如果当前节点没有父节点,或者父节点类型不是元素节点,则返回null。
<div id="d1">hello world</div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.parentElement); // body
// 将父元素节点的背景颜色设置为红色
div1.parentElement.style.backgroundColor = 'red';
</script>
firstChild、lastChild
firstChild属性返回当前节点的第一个子节点,如果当前节点没有子节点,则返回null。
lastChild属性返回当前节点的最后一个子节点,如果当前节点没有子节点,则返回null。用法与firstChild属性相同。
<div id="d1">hello world<div>我是子节点</div></div>
<div id="d2"><div>我是子节点</div></div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.firstChild); // hello world
console.log(div1.lastChild); // <div>我是子节点</div>
var div2 = document.getElementById('d2');
console.log(div2.firstChild); // <div>我是子节点</div>
</script>
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>
三、Node 接口的方法
appendChild
appendChild方法接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点。该方法的返回值就是插入文档的子节点。
<script>
// 创建元素节点p
var p = document.createElement('p');
// 向p标签插入内容
p.innerHTML = '我是一个p标签';
// 将节点插入到body中
document.body.appendChild(p);
</script>
insertBefore()
insertBefore方法用于将某个节点插入父节点内部的指定位置。
insertBefore方法接受两个参数,第一个参数是所要插入的节点newNode,第二个参数是父节点parentNode内部的一个子节点referenceNode。newNode将插在referenceNode这个子节点的前面。返回值是插入的新节点newNode。
<div id="parentElement">
<span id="childElement">foo bar</span>
</div>
<script>
//创建一个新的、普通的<span>元素
var sp1 = document.createElement("span");
// 向span标签插入内容
sp1.innerHTML = '我是span标签'
//插入节点之前,要获得节点的引用
var sp2 = document.getElementById("childElement");
//获得父节点的引用
var parentDiv = sp2.parentNode;
//在DOM中在sp2之前插入一个新元素
parentDiv.insertBefore(sp1, sp2);
</script>
removeChild()
removeChild方法接受一个子节点作为参数,用于从当前节点移除该子节点。返回值是移除的子节点。
<div id="d1">
<span id="s1">我是span标签</span>
</div>
<script>
var span1 = document.getElementById('s1');
span1.parentNode.removeChild(span1);
</script>
replaceChild()
replaceChild方法用于将一个新的节点,替换当前节点的某一个子节点。
<div id="d1">
<span id="s1">我是span标签</span>
</div>
<script>
var span1 = document.getElementById('s1');
//创建一个新的div标签
var div1 = document.createElement("div");
// 向div标签插入内容
div1.innerHTML = '我是div1标签';
// 节点替换
span1.parentNode.replaceChild(div1, span1);
</script>
四、Document类型
getElementById()
返回匹配指定 id 的一个元素。
<div id="d1">我是一个div标签</div>
<script>
// 查找id为d1的标签
var div = document.getElementById('d1');
console.log(div);
</script>
getElementsByTagName()
返回一个HTMLCollection
(伪数组),包含匹配指定标签名的所有元素。
<p>我是p标签</p>
<p>我是p标签</p>
<p>我是p标签</p>
<script>
// 查找所有p标签
var p = document.getElementsByTagName('p');
console.log(p);
</script>
getElementsByClassName()
返回一个HTML集合HTMLCollection
(伪数组),包含匹配指定类名的所有元素。
<div class="div1">我是div标签</div>
<div class="div1">我是div标签</div>
<div class="div1">我是div标签</div>
<script>
// 查找class为div1的标签
var div = document.getElementsByClassName('div1');
console.log(div);
</script>
document.querySelector()
返回文档中匹配指定的CSS选择器的第一元素
<div id="div1">我是一个div</div>
<div id="div1">我是一个div</div>
<script>
document.querySelector("#div1").innerHTML = "Hello World!";
</script>
document.querySelectorAll()
document.querySelectorAll() 是 HTML5中引入的新方法,返回文档中匹配的CSS选择器的所有元素节点列表
<div class="div1">我是一个div</div>
<div class="div1">我是一个div</div>
<script>
console.log(document.querySelectorAll(".div1"));
var x = document.querySelectorAll(".div1");
x[0].innerHTML = '我是新的div';
</script>
document.createElement(element)
创建一个新的HTML元素,要与appendChild() 或 insertBefore()方法联合使用。其中,appendChild() 方法在节点的子节点列表末添加新的子节点。insertBefore() 方法在节点的子节点列表任意位置插入新的节点。
<script>
// 创建元素节点p
var p = document.createElement('p');
// 向p标签插入内容
p.innerHTML = '我是一个p标签';
// 将节点插入到body中
document.body.appendChild(p);
</script>
document.write()
向文档写入文本或 HTML 表达式 或 JavaScript 代码。
<script>
document.write("<p>Hello world!</p>");
document.write("<span>Hello DOM!</span>");
document.write("Hello Weekend!");
</script>
五、Element类型
element.innerHTML
属性设置或获取HTML语法表示的元素的后代。
<div id="div1">我是一个div</div>
<script>
var d1 = document.getElementById('div1');
// 获取
console.log(d1.innerHTML);
// 设置
d1.innerHTML = '我是新的内容'
</script>
element.attribute = value
修改已经存在的属性的值
<div id="div1">123</div>
<script>
var d1 = document.getElementById('div1');
// 直接将已经存在的属性进行修改
d1.id = 'div2';
</script>
element.getAttribute()
返回元素节点的指定属性值。
<div id="div1">我是一个div</div>
<script>
var div = document.getElementById('div1');
console.log(div.getAttribute('id')); // div1
</script>
element.setAttribute(attribute, value)
把指定属性设置或更改为指定值。
<div id="div1">我是一个div</div>
<script>
var d1 = document.getElementById('div1');
// 设置div1的class为divCla
d1.setAttribute('class', 'divCla');
</script>
element.style.property
设置或返回元素的 style 属性。
<div id="div1">我是一个div</div>
<script>
var d1 = document.getElementById('div1');
// 获取div1的style样式
console.log(d1.style);
// 设置div1的style
d1.style.backgroundColor = 'red';
</script>
六、Text类型
appendData(text)
追加文本
deleteData(beginIndex,count)
删除文本
insertData(beginIndex,text)
插入文本
replaceData(beginIndex,count,text)
替换文本
splitText(beginIndex)
从beginIndex位置将当前文本节点分成两个文本节点
document.createTextNode(text)
创建文本节点,参数为要插入节点中的文本
substringData(beginIndex,count)
从beginIndex开始提取count个子字符串
<div id="container"></div>
<script>
// 创建文本节点
var textNode = document.createTextNode('Hello World!');
// 获取container
var div = document.getElementById('container');
// 将文本节点插入container
div.appendChild(textNode);
// 替换文本
textNode.replaceData(0,5,'Hi');
// 插入文本
textNode.insertData(0, 'Hello')
</script>