从DOM的角度去理解,整个html文档被称为对象(document对象)。文档中每个标签元素,以及元素的内容,属性,样式都是节点对象
节点分类:
- 元素节点(html元素)
- 文本节点(元素内容)
- 属性节点(html的属性)
- 文档节点(document)
- 根节点(<html>)
- 注释节点
HTML的文档结构:树形结构;节点关系:父子关系 兄弟关系
获取节点对象
- getElement系列--- getelementById(),获取元素节点
- querySelector系列---ele.innerHTML
- 层次关系获取节点
属性名称 | 描述 |
parentNode | 返回节点的父节点 |
childNodes | 返回子节点集合,childNodes[i] |
firstChild | 返回节点的第一个子节点,最普遍的用法是访问该元素的文本节点 |
lastChild | 返回节点的最后一个子节点 |
nextSibling | 下一个节点 |
previousSibling | 上一个节点 |
<div>
<p>hello</p>
</div>
<script>
var oDiv=document.querySelector('div')
console.log(oDiv.children) //获取第一个元素p节点P,是个伪数组
console.log(oDiv.firstElementChild) //获取一个节点,不是伪数组,第一个元素节点P标签 <p>hello</p>
</script>
- 层次关系获取元素节点
属性名称 | 描述 |
firstElementChild | 返回节点的第一个子节点,最普遍的用法是访问该元素的文本节点 |
lastElementChild | 返回节点的最后一个子节点 |
nextElementsibling | 下一个节点 |
previousElementSibling | 上一个节点 |
- 获取元素节点的所有属性节点: attributes
-
<ul> <li id="a" a="100" test="test">hello</li> </ul> <script> var oli=document.querySelector('#a') console.log(oli.attributes) </script>
这里li有三个属性,id/a/test三个,所以获取到了三个
<div class='root'>
<p>元素2 </p>
<p>元素3 </p>
<p>元素4 </p>
</div>
<script>
var divEle = document.querySelector('.root')
// //访问孩子节点
console.log(' divEle.childNodes ', divEle.childNodes)
// //第一个孩子
console.log('divEle firstChild ',divEle.firstChild)
// //最后一个孩子
console.log('divEle lastChild ',divEle.lastChild)
console.log('divEle firstChild.nextSibling ',divEle.firstChild.nextSibling)
console.log('divEle.children ',divEle.children)
console.log('divEle.firstElementChild ',divEle.firstElementChild)
console.log('divEle.lastElementChild ',divEle.lastElementChild)
console.log('divEle.nextElementSibling ',divEle.firstElementChild.nextElementSibling)
console.log('divEle.parentElement ',divEle.lastElementChild.parentElement)
console.log('body ', document.body)
console.log('html ', document.documentElement)
console.log('head ', document.head)
</script>
元素与元素之间存在元素节点
案例:点击购物车的+号,使数量增加,并计算出总价
点击加号,数量加一,计算该商品总价,显示到总价栏
分析:
1. 给加号绑定点击事件
2. 改变数量
3. 获取单价 * 数量
html:
<table class="container">
<tr>
<th>商品图片</th>
<th>商品信息</th>
<th>单价</th>
<th>数量</th>
<th>总价</th>
<th>操作</th>
</tr>
<tr>
<td><img src="https://img0.baidu.com/it/u=2948639727,75026022&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=628">
</td>
<td>javascript高级编程</td>
<td>¥34.32</td>
<td> <input type='button' value="-" name="minus" /><input type="text" name="amount" value="0" /><input
type="button" value="+" name="plus" /></td>
<td>¥0</td>
<td>移入收藏
<br>删除
</td>
</tr>
<tr>
<td><img src='http://t14.baidu.com/it/u=1194753268,1223449310&fm=224&app=112&f=JPEG?w=500&h=500'></td>
<td>java从入门到精通</td>
<td>¥24.54</td>
<td> <input type='button' value="-" name="minus" /><input type="text" name="amount" value="0" /><input
type="button" value="+" name="plus" /></td>
<td>¥0</td>
<td>移入收藏
<br>删除
</td>
</tr>
</table>
JS部分:
function onplus() {
var plusEles = document.querySelectorAll('input[name="plus"]') //获取到+号所在的input
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//获取单价金额
price = price.substring(1) //¥34.42 去掉¥
//计算价格
var totalPrice = price * amountEle.value
this.parentElement.nextElementSibling.innerHTML = `¥${totalPrice.toFixed(2)}`
}
}
}
onplus()
非常规节点获取:
获取html根节点:document.documentElement
获取body节点:document.body
获取head:document.head
节点属性:
- | nodeType | nodeName | nodeValue |
元素节点 | 1 | 标签名大写 | null |
属性节点 | 2 | 属性名 | 属性值 |
文本节点 | 3 | #text | 文本内容 |
<div>元素一</div>
<script>
var divEle=document.querySelector('div')
console.log('nodetype',divEle.nodeType,'nodeName',divEle.nodeName,'nodevalue',divEle.nodeValue)
动态创建Dom节点
- 创建DOM节点:document.createElement('div')
- 创建文本节点:document.createTextNode(‘元素一’)
<body>
<div class="root"></div>
<script>
function test1(){
// 创建结点
var pEle=document.createElement('p')
//添加结点
var divEle=document.querySelector('.root')
divEle.appendChild(pEle)
}
test1()
</script>
</body>
创建了一个节点,你需要添加内容才会显示该结点
如何在创建的结点中编写内容?这里介绍两种方式
<body>
<div class="root"></div>
<script>
function test1(){
// 创建结点
var pEle=document.createElement('p')
// 添加内容元素一
pEle.innerHTML='元素一'
// var textNode=document.createTextNode('元素一')
// pEle.appendChild(textNode)
// 添加结点
var divEle=document.querySelector('.root')
divEle.appendChild(pEle)
}
test1()
</script>
</body>
添加Dom节点
- 父节点.appendChild(子节点) 添加
- 父节点 .insertBefore(新节点,原子节点)插入
var divEle = document.querySelector('.root')
// divEle.appendChild(pEle)
var oldPEle = divEle.firstElementChild
divEle.insertBefore(pEle,oldPEle)
删除Dom节点
- 父节点.removeChild(子节点)
- 节点.remove()
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() }
替换Dom节点
- 父节点.replaceChild(新节点,原节点)
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) }
克隆节点
- 节点.cloneNoede() false | true
- ==>返回克隆的新节点
// 克隆节点 var cloneBtn = document.querySelector('.cloneBtn') cloneBtn.onclick = function(){ var divEle = document.querySelector('.root') var newDivEle = divEle.cloneNode(true) // 添加body下 document.body.appendChild(newDivEle) }
获取元素偏移量:
就是元素在页面上的什么位置
我们有几个属性来获取,offsetLeft 和 offsetTop , offsetWidth 和 offsetHeight
offsetLeft 和 offsetTop:左边和上边的偏移量,没有定位的情况下,获取元素边框外侧到页面内侧的距离,有定位的情况下是获取元素边框外侧到定位父级边框内侧的距离
offsetWidth 和 offsetHeight:获取元素内容宽高+padding宽高+border宽度的和
元素尺寸:
offsetWidth = 内容width + padding + border
clientWidth = 内容width + padding
window.getComputedStyle(divEle).width = 内容width
操作数据综合练习:
<!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>todoList</title>
</head>
<body>
<div class="container">
<input type="text" placeholder="请输入内容" /><button>确定</button>
<ul></ul>
</div>
<script>
/*
todoList应用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(){
//删除数据
// [10,20,30,40]
// arr.splice(index,1)
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>
</html>