JavaScript
DOM 节点
了解 DOM 节点
+ 我们的页面是由一个一个的节点组成
+ 页面的每一个组成部分都是一个节点
+ 常用的节点有以下几种
1. document
=> 一个页面中最大的节点,只能有一个
=> 承载所有节点的容器,不属于元素
=> 根节点
2. html
=> 一个页面中最大的元素节点
=> 承载所有其他节点的
=> 根元素节点
3. 元素节点
=> head / body / div / ul / table / ...
=> 只是不同的标签在页面中的表现形式不一样
=> 特点: 都是页面的标签
4. 文本节点
=> 每一段文本内容都是一个文本节点
=> 包含 换行 和空格
=> 一般作为元素节点的子节点存在,用来表示该元素节点在页面上显示的内容
5. 属性节点
=> 注意:属性节点不作为独立节点出现,必须依赖元素
=> 因为没有元素,属性节点就是文本
6. 注释节点
=> 作为独立节点出现
=> 作为说明文本使用
节点操作
节点操作
+ 不光操作元素
+ 还要操作 注释节点 文本节点 属性节点
获取节点
+ 两个大类
1. 方法
+ 上一章写的
+ 获取元素节点
2. 属性
+ 获取节点有如下属性
childNodes
+ 语法: 元素.childNodes
+ 得到:元素的所有子节点(伪数组)
<!--
div 元素内有多少个 子节点
1. 文本节点 (一个换行 + 四个空格 + hello + 一个换行 + 四个空格)
2. 元素节点 (p标签)
3. 文本节点 (一个换行 + 四个空格 + world + 一个换行 + 四个节点)
4. 元素节点 (p标签)
5. 文本节点 (一个换行 + 四个空格)
6. 注释节点
7. 文本节点 (一个换行 + 两个空格)
-->
<div>
hello
<p>你好</p>
world
<p>世界</p>
<!-- 我是一段注释 -->
</div>
// 获取元素
var div = document.querySelector('div')
// 1. childNodes
var child = div.childNodes
console.log(cn)
children
+ 语法: 元素.children
+ 得到: 元素的所有 子元素节点(伪数组)
// 2. children
var childEle = div.children
console.log(childEle)
firstChild 和 lastChild
firstChild
+ 语法: 元素.firstChild
+ 得到: 元素的第一个子节点
lastChild
+ 语法: 元素.lastChild
+ 得到: 元素的最后一个子节点
// 3. firstChild
var first = div.firstChild
console.log(first)
console.log(typeof first) // object, 不是字符串
// 5. lastChild
var last = div.lastChild
console.log(last)
firstElementChild 和 lastElementChild
firstElementChild
+ 语法: 元素.firstElementchild
+ 得到: 元素的第一个子元素节点
lastElementChild
+ 语法: 元素.lastElementchild
+ 得到: 元素的最后一个子元素节点
// 4. firstElementChild
var firstEle = div.firstElementChild
console.log(firstEle)
// 6. lastElementChild
var lastEle = div.lastElementChild
console.log(lastEle)
previousSibling 和 nextSibling
previousSibling
+ 语法: 元素.previousSibling
+ 得到: 元素的上一个兄弟节点(哥哥节点)
nextSibling
+ 语法: 元素.nextSibling
+ 得到: 元素的下一个兄弟节点(弟弟节点)
<p>我是 div 上面的 p 标签</p>
<div>
hello
<p>你好</p>
world
<p>世界</p>
<!-- 我是一段注释 -->
</div>
<p>我是 div 下面的 p 标签</p>
// 7. previousSibling
var prev = div.previousSibling
console.log(prev) // 换行+两个空格
// 9. nextSibling
var next = div.nextSibling
console.log(next)
previousElementSibling 和 nextElementSibling
previousElementSibling
+ 语法: 元素.previousElementSibling
+ 得到: 元素的上一个兄弟元素节点(哥哥元素)
nextElementSibling
+ 语法: 元素.nextElementSibling
+ 得到: 元素的下一个兄弟元素节点(弟弟元素)
// 8. previousElementSibling
var prevEle = div.previousElementSibling
console.log(prevEle)
// 10. nextElementSibling
var nextEle = div.nextElementSibling
console.log(nextEle)
parentNode
+ 语法: 元素.parentNode
+ 得到: 该元素的 父节点
+ 父节点: 大部分的时候是元素,有特殊的 document
parentElement
+ 语法: 元素.parentElement
+ 得到: 该元素的 父元素节点
// 11. parentNode
var parent1 = div.parentNode
var parent2 = div.parentNode.parentNode
var parent3 = div.parentNode.parentNode.parentNode
console.log(parent1, parent2, parent3)
// 12. parentElement
var parentEle = div.parentElement.parentElement.parentElement
console.log(parentEle) // null
attributes
获取属性节点:
=> 元素身上放的属性
=> 每一个属性是一个节点
=> 通过 attributes 属性返回指定节点的属性集合,即 NamedNodeMap
=> 语法: 元素.attributes
=> 语法: 元素.attributes[索引]
// 13. attributes
var attrs = div.attributes
console.log(attrs)
节点属性
+ 节点属性
=> 用来描述这个节点的信息
=> 不同的节点有相同的属性名,但是值不一样
=> 例子:
-> 元素节点: 编号 001
-> 属性节点: 编号 002
+ 节点属性有三个
nodeType
1. nodeType
=> 以数字的形式来表示一个节点类型
=> 一种节点的编号
=> 元素节点: 1
=> 属性节点: 2
=> 文本节点: 3
=> 注释节点: 8
// 准备一系列节点
// 获取元素节点
var div = document.querySelector('div')
// 属性节点
var attr = div.attributes[0]
// 文本节点
var text = div.childNodes[2]
// 注释节点
var comment = div.childNodes[1]
console.log('元素节点', div)
console.log('属性节点', attr)
console.log('文本节点', text)
console.log('注释节点', comment)
console.log('===================')
// 节点属性 - 节点类型
console.log('元素节点的节点类型', div.nodeType)
console.log('属性节点的节点类型', attr.nodeType)
console.log('文本节点的节点类型', text.nodeType)
console.log('注释节点的节点类型', comment.nodeType)
nodeName
2. nodeName
=> 节点的名称
=> 元素节点: 大写标签名(全大写)
=> 属性节点: 属性名
=> 文本节点: 所有文本节点名称全部叫做 #text
=> 注释节点: 所有注释节点的名称全部叫做 #comment
// 节点属性 - 节点名称
console.log('元素节点的节点名称', div.nodeName)
console.log('属性节点的节点名称', attr.nodeName)
console.log('文本节点的节点名称', text.nodeName)
console.log('注释节点的节点名称', comment.nodeName)
nodeValue
3. nodeValue
=> 节点的值
=> 元素节点: null
=> 属性节点: 属性值
=> 文本节点: 文本内容(包含换行和空格)
=> 注释节点: 注释内容(包含换行和空格)
// 节点属性 - 节点的值
console.log('元素节点的节点的值', div.nodeValue)
console.log('属性节点的节点的值', attr.nodeValue)
console.log('文本节点的节点的值', text.nodeValue)
console.log('注释节点的节点的值', comment.nodeValue)
创建节点
创建节点
+ 使用 JS 的语法来创造一个节点出来
1. createElement()
+ 语法: document.createElement('标签名')
+ 返回值: 一个元素节点
2. createTextNode()
+ 语法: document.createTextNode('文本内容')
+ 返回值: 一个文本节点,不是字符串
+ 不常用
3. createComment()
+ 语法:document.createComment('注释内容')
+ 返回值: 一个注释节点
+ 不常用
4. createAttribute()
+ 语法: document.createAttribute('属性名')
=> 要添加属性值, 节点.value = '属性值'
+ 返回值: 一个属性节点
+ 更不常用
不常用因为创建这些节点后还要多一步:将该节点添加到元素上,所以会耗内存,不如直接使用点语法或innerText这些来操作元素属性和文本内容,注释直接写
div.id = 'box'
div.innerText = 'hello world'
// 1. 创建元素节点
var div = document.createElement('div')
console.log(div)
// 2. 创建文本节点
var text = document.createTextNode('hello world')
console.log(text)
console.log(text.nodeType) // 3
// 3. 创建注释节点
var comment = document.createComment('我是一段注释内容')
console.log(comment)
// 4. 创建属性节点
var attr = document.createAttribute('id')
attr.value = 'box'
console.log(attr)
插入节点
插入节点
+ 把一个节点插入到另一个节点里面
1. appendChild()
+ 语法: 父节点.appendChild(子节点)
+ 作用: 把子节点插入到父节点里面,放在最后一个节点的位置
<div class="box">
<!-- 我把创建的节点插入到这个 div 里面 -->
<p>我是 div 里面本身的 p 标签</p>
</div>
// 获取元素
var box = document.querySelector('div')
// 创建一个节点
var span = document.createElement('span')
span.innerText = '我是新来的 span 节点'
// 再创建一个节点
var h1 = document.createElement('h1')
// 1. appendChild
// 把 span 节点插入到 h1 节点里面
h1.appendChild(span)
// 把 h1 节点插入到 box 节点里面
box.appendChild(h1)
2. insertBefore()
+ 语法: 父节点.insertBefore(要插入的子节点,哪一个子节点前面)
+ 作用: 把子节点插入到指定父节点的指定子节点的前面
<div class="box">
<!-- 我把创建的节点插入到这个 div 里面 -->
<p>我是 div 里面本身的 p 标签</p>
</div>
// 获取元素
var box = document.querySelector('div')
var p = document.querySelector('p')
// 创建一个节点
var span = document.createElement('span')
span.innerText = '我是新来的 span 节点'
// 再创建一个节点
var h1 = document.createElement('h1')
// 2. insertBefore()
// 把 span 追加到 h1 里面
h1.appendChild(span)
// 把 h1 插入到 box 节点中的 p 节点前面
box.insertBefore(h1, p)
删除节点
删除节点
+ 删除一个已经存在的节点
+ 可以在创建的节点里面删除,也可以直接在页面元素中删除
1. removeChild()
+ 语法: 父节点.removeChild(子节点)
+ 作用: 把子节点从父节点里移除
2. remove()
+ 语法: 节点.remove()
+ 作用: 把自己移除
<div>
<p>我是 div 里面的 p 标签</p>
</div>
// 获取元素
var div = document.querySelector('div')
var p = document.querySelector('p')
// removeChild()
div.removeChild(p)
// remove()
// 把 div 从自己的父节点(body)里面移除
div.remove()
替换节点
替换节点
+ 用一个节点替换一个已经存在的节点
+ 可以直接替换页面元素,也可以替换我们自己创建的节点
1. replaceChild()
+ 语法: 父节点.replaceChild(新节点, 旧节点)
+ 作用: 在父节点下,用新的节点替换旧的节点
// 获取元素
var div = document.querySelector('div')
var p =document.querySelector('p')
// 创建元素
var span = document.createElement('span')
span.innerText = '我是新来的 span 标签'
// 1. replaceChild()
// div.replaceChild(span, p)
div.replaceChild(span, div.firstChild)
克隆节点
克隆节点
- 把某一个节点复制一份一模一样的出来
- cloneNode()
=> 语法: 节点.cloneNode(参数)
-> 参数选填,默认是 false,不克隆后代节点
-> 我们可以选填 true, 表示克隆所有后代节点
=> 返回值: 一个克隆好的节点
<style>
*{
margin: 0;
padding: 0;
}
div{
width: 300px;
height: 300px;
background-color: skyblue;
margin: 30px;
}
button{
width: 200px;
height: 30px;
}
</style>
</head>
<body>
<div id="box" class="box">
<button>按钮</button>
</div>
<hr>
<hr>
<script>
// 获取元素
var div = document.querySelector('div')
// 1. cloneNode()
var cloneDiv = div.cloneNode()
var cloneDiv = div.cloneNode(true)
// 2. 插入页面
document.body.appendChild(cloneDiv)
console.log(cloneDiv)
</script>
</body>
节点操作总结
+ 获取节点(之前写过获取DOM元素,现在写的包含但不限于节点)
+ 创建节点
=> 通过 JS 的语法来制造一个标签 / 文本 / 注释
1. createElement()
2. createtextNode()
3. createComment()
4. createAttribute()
+ 插入节点
=> 把我创建的节点插入另一个节点中,使出现父子结构
1. appendChild()
2. insertBefore()
+ 删除节点
=> 把一个已经存在的节点移除
1. removeChild()
2. remove()
+ 替换节点
=> 我创建一个节点去替换一个已经存在的节点
1. replaceChild()
+ 克隆节点
=> 把一个已经存在的节点复制一份出来
1. cloneNode()
-> 参数默认为 false,不克隆子节点
-> 选填 true,克隆后代节点