一、DOM节点对象
dom节点对象
html标签元素
<h2 id="title">元素一</h2>
dom节点对象
=>从dom角度,整个html文档就是一个对象(document 文档对象),文档中每个标签元素,以及元素的内容,属性,样式都是节点属性
=>节点对象分类
(元素节点 文本节点 )document文档节点 注释节点
=> html文档结构
树型结构

=> 节点关系
父子关系 兄弟关系
根节点:在HTML文档中,html就是根节点。
父节点:一个节点之上的节点就是该节点的父节点,例如ul的父节点就是body,body的父节点就是html。
子节点:一个节点之下的节点就是该节点的子节点,例如ul就是body的子节点。
兄弟节点:如果多个节点在同一层次,并拥有相同的父节点,那么这几个节点就是兄弟节点。
body下面有7个节点,4个空节点
二、获取节点
节点分类
元素节点 文本节点 属性节点
获取节点对象
1. getElement系列
getElementById()
元素节点
2.querySelector 系列
ele.innerHTML
3.层次结构
父节点 ->所有子节点 childNodes
->firstChild
->lastChild
->元素子节点 children
->firstElementChild
->lastElsementChild
兄弟 ->nextElementSibling
->parentElement
属性名称 |
描述 |
parentNode |
返回节点的父节点 |
childNodes |
返回子节点集合,childNodes[i] |
firstChild |
返回节点的第一个子节点,最普遍的用法就是访问该元素的文本节点 |
lastChild |
返回节点的最后一个子节点 |
naextChild |
下一个节点 |
previousSibling |
上一个节点 |
body下面有7个节点,4个空节点

4.非常规节点
<body>
<div class="root">
1
<p>元素一</p>
2
<p>元素二</p>
3
<p>元素三</p>
4
</div>
<script>
// 获取div父节点
var divEle = document.querySelector('.root')
console.log('divEle.childNodes', divEle.childNodes)
console.log('divEle. firstchild', divEle.firstChild)
console.log('divEle.lasthild',divEle.lastChild)
console.log('divEle.firstchild.nextsibling',divEle.firstChild.nextSibling)//返回第一个文本节点的下一个节点
console.log('divEle.childen:',divEle.children)//返回某一节点下所有子一级的元素节点
console.log('divEle.firstElementChild:',divEle.firstElementChild)//返回某一节点下第一个子一级的元素节点
console.log('divEle.lastElementChild:',divEle.lastElementChild)//返回某一节点下最后一个子一级的元素节点
console.log('divEle.nextElementSibling',divEle.nextElementSibling)//父亲节点的下一个节点为script
console.log('divEle.parentElement',divEle.lastElementChild.parentElement)//返回最后一个子节点的父节点
console.log('body',document.body)
console.log('html',document.html)
console.log('head',document.head)
</script>
例子:购物车找节点示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车找节点示例</title>
<style>
* {
padding: 0;
margin: 0;
}
.container {
width: 1200px;
margin: 100px auto;
}
.container tr {
line-height: 40px;
text-align: center;
}
.containertr,
th,
td {
border-bottom: 1px solid gray;
}
.container tr input {
width: 20px;
text-align: center;
}
</style>
</head>
<body>
<table class="container">
<tr>
<th>商品图片</th>
<th>商品信息</th>
<th>单价</th>
<th>数量</th>
<th width="100px">总价</th>
<th>操作</th>
</tr>
<tr>
<td> <img src="https://img2.baidu.com/it/u=1499633017,1319149509&fm=253&fmt=auto&app=138&f=JPEG?w=100&h=100"
alt="图片一"></td>
<td>javascript高级编程</td>
<td>¥28.98</td>
<td>
<input type="button" value="-" name="minus"><input type="text" value="0" name="amount"><input
type="button" name="plus" value="+">
</td>
<td>¥0</td>
<td>移入收藏<br>删除</td>
</tr>
<tr>
<td> <img src="https://img2.baidu.com/it/u=1499633017,1319149509&fm=253&fmt=auto&app=138&f=JPEG?w=100&h=100"
alt="图片一"></td>
<td>css高级编程</td>
<td>¥16.68</td>
<td>
<input type="button" value="-" name="minus"><input type="text" value="0" name="amount"><input
type="button" value="+" name="plus">
</td>
<td>¥0</td>
<td>移入收藏<br>删除</td>
</tr>
</table>
<script>
/*
点击加号,数量加一,计算该商品总价,显示到总价栏
分析:
1.给加号绑定点击事件
2.改变数量
3.获取单价*数量
*/
function onPlus() {
var plusEles = document.querySelectorAll('input[name="plus"]')
for (var i = 0; i < plusEles.length; i++) {
var plusEle = plusEles[i] //加号节点对象
// 给加号绑定事件
plusEle.onclick = function () {
// this关键字:当前点击的节点对象
var amountEle = this.previousElementSibling
amountEle.value++
//获取单价
var priceEle = this.parentElement.previousElementSibling
var price = priceEle.innerHTML
// str.substring(开始索引,结束索引)
price = price.substring(1)//只有一个参数,表示截取从索引号开始所有子字符串
// // 计算价格
var totalPrice = price * amountEle.value
console.log(totalPrice)
var totalPriceEle = this.parentElement.nextElementSibling
totalPriceEle.innerHTML = `¥${totalPrice.toFixed(2)}`
}
}
}
onPlus()
</script>
</body>
</html>
三、节点属性
nodeType nodeName nodeValue
元素节点 1 标签名大写 null
属性节点 2 属性名 属性值
文本节点 3 #text 文本内容
<body>
<div>元素一</div>
<script>
var divEle=document.querySelector('div')
divEle=divEle.firstChild
console.log('nodeType',divEle.nodeType,'nodeName',divEle.nodeName,'nodeValue',divEle.nodeValue)
</script>
</body>
四、动态操作DOM
创建dom 节点
document.creatElement('div') //<div></div>
document.createTextNode('元素一')
添加dom节点
父节点.appendChild(子节点) 增加节点
父节点.insertBefore(新节点,原子节点) 插入节点
删除节点
父节点.removeChild(子节点)
节点.remove()
替换节点
父节点.replaceChild(新节点,原节点)
克隆节点
节点.cloneNode()
true|falase
=>返回克隆的新节点
<body>
<div class="root"></div>
<!-- <button class="">添加节点</button> -->
<button class="removeBtn">删除节点</button>
<button class="replaceBtn">替换节点</button>
<button class="cloneBtn">克隆节点</button>
<script>
function test1() {
//1. 创建节点
var pEle = document.createElement('p')//<p></p>
// pEle.innerHTML='元素一'
var textNode = document.createTextNode('元素一')
pEle.appendChild(textNode)//增加一个文本内容为元素一的节点
// console.log(textNode)
//2. 添加节点
var divEle = document.querySelector('.root')
// divEle.appendChild(pEle)
// console.log(divEle)
var oldPEle = divEle.firstElementChild
divEle.insertBefore(pEle, oldPEle)
}
test1()
function test2() {
var divEle = document.querySelector('.root')
var oldPEle = divEle.firstElementChild
// divEle.removeChild(oldPEle)
oldPEle.remove()
}
// 删除节点
var removeBtn = document.querySelector('.removeBtn')
removeBtn.onclick = function () {
test2()
}
// 替换节点
var replaceBtn = document.querySelector('.replaceBtn')
replaceBtn.onclick = function () {
var h2Ele = document.createElement('h2')
h2Ele.innerHTML = '标题'//<h2>标题</h2>
var divEle = document.querySelector('.root')
var pEle = document.querySelector('.root>p')
divEle.replaceChild(h2Ele, pEle)
}
// 克隆节点
var cloneBtn = document.querySelector('.cloneBtn')
cloneBtn.onclick = function () {
var divEle=document.querySelector('.root')
var newDivEle = divEle.cloneNode(true)
// 添加body下
document.body.appendChild(newDivEle)
}
</script>
</body>
五、元素偏移量
offsetLeft 和 offsetTop
offsetWidth 和 offsetHeight

<style>
*{
margin: 0;
padding:0;
}
div{
width: 400px;
height: 400px;
background-color: skyblue;
margin: 100px;
padding: 50px;
position: relative;
}
div p{
width: 100px;
height: 100px;
background: pink;
}
</style>
</head>
<body>
<div>
<p></p>
</div>
<script>
function test1(){
var pEle=document.querySelector('p')
console.log('pEle.offsetTop',pEle.offsetTop)
console.log('pEle.offsetLeft',pEle.offsetLeft)
}
test1()
</script>
六、获取元素尺寸
offsetWidth = 内容width + padding + border
clientWidth = 内容width + padding
window.getComputedStyle(divEle).width = 内容width

<style>
*{
padding:0;
margin: 0;
}
div{
width: 200px;
height: 200px;
padding: 20px;
margin: 100px;
border:10px solid palegreen;
background-color:skyblue;
}
</style>
</head>
<body>
<div></div>
<script>
function test1(){
var div=document.querySelector('div')
console.log('width:',window.getComputedStyle(div).width)
console.log('clientwidth:',div.clientWidth)//内容+padding
console.log('offsetWidth:',div.offsetWidth) //内容+padding+border
}
test1()
</script>
七、toList 1.0和2.0
toList1.0
<body>
<div class="container">
<input type="text" placeholder="请输入内容"><button>确定</button>
<ul></ul>
</div>
<script>
/*
1.详细描述需求
点击确定按钮,获取输入框内容,显示到ul节点下
分析:复杂问题简单化
1.绑定点击事件
2.获取输入框内容
3.创建li子节点,输入框作用子节点文本内容,追加给ul
*/
var btn = document.querySelector('button')
btn.onclick = function () {
// 获取输入框内容
var inputEle = document.querySelector('input')
var inputValue = inputEle.value
// 3.创建li子节点,输入框作用子节点文本内容,追加给ul
var liEle = document.createElement('li')
liEle.innerHTML = inputValue //<li>css</li>
// 4.追加元素
var ulEle = document.querySelector('ul')
ulEle.appendChild(liEle)
// 5.清空内容
inputEle.value = ''
// 绑定删除事件
onDelete()
}
//分析:遍历所有里绑定点击事件,删除当亲点击的元素
function onDelete() {
var liEles = document.querySelectorAll('ul>li')
for (var i=0; i < liEles.length; i++) {
var liEle = liEles[i] //li元素
// 绑定事件
liEle.onclick = function () {
// 删除当前点击的元素
// this关键字:当前点击的元素节点对象
this.remove()
}
}
}
</script>
</body>
toList2.0(重要!!!)
<body>
<div class="container">
<input type="text" placeholder="请输入内容"><button>确定</button>
<ul></ul>
</div>
<script>
/*
toList应用2.0版本
1.0节点操作 了解
2.0数据操作 重点
*/
var arr=['html','css']
/*
数据操作--实现列表
遍历数组,拼接字符串,将字符串作用内容设置给显示元素
点击确定按钮,获取输入框内容,添加数组
*/
function showList(){
var liArr=arr.map(function(item,index){
return`<li data-index="${index}">${item}</li>`
})
var liStr=liArr.join('')
var ulEle=document.querySelector('ul')
ulEle.innerHTML=liStr
onDelete()//绑定删除事件
}
// 删除元素
function onDelete(){
var liEles=document.querySelectorAll('ul>li')
// 循环遍历所有li绑定事件
for(var i=0;i<liEles.length;i++){
var liEle=liEles[i]
liEle.onclick=function(){
// 删除数据
var index=this.dataset.index
arr.splice(index,1)
showList()//刷新
}
}
}
// 添加元素
var btn=document.querySelector('button')
btn.onclick=function(){
var inputEle=document.querySelector('input')
var inputValue=inputEle.value
arr.push(inputValue)
inputEle.value=''//清空输入框
showList()//刷新
}
showList()//初始化执行
</script>
</body>