目录
6.获取非行间样式【上一章已写过一种,这里主要是兼容性问题】
1.DOM节点对象
规定:从DOM角度,整个html文档就是一个对象,文档中的每一个标签元素,以及元素内容、样式、属性都是节点对象
节点对象的分类:
1.元素节点:每个HTML元素
2.文本节点:HTML元素内的文本
3.属性节点:每个HTML属性
4.document文档节点:整个文档
5.注释节点:注释
html文档结构:
树形结构
节点关系:
根节点:在HTML文档中,html就是根节点
父节点:一个节点之上的节点就是该节点的父节点
子节点:一个节点之下的节点就是该节点的子节点
兄弟节点:如果过个节点在同一层次,并拥有相同的父节点。那么这个节点就是兄弟节点
父子关系、兄弟关系
2.获取节点对象
元素节点:【上一章节已做】
getElement系列
querySelector系列
文本节点:
innerHTML、innerText、value
属性节点:
getAttribute系列
3.获取节点除上一章节外
1.层次关系获取节点:
childNodes获取某一节点下的子节点
属性名称 | 描述 |
parentNode | 返回节点的父节点 |
childNodes | 返回子节点集合,childNodes[i]【空白也算一个文本节点】 |
firstChild | 返回节点的第一个子节点,最普通的用法是访问该元素的文本节点 |
lastChild | 返回节点的最后一个子节点 |
nextSibling | 下一个节点【同级】 |
previousSibling | 上一个节点【同级】 |
<body>
<div class="root">
<p>元素1</p>
<p>元素2</p>
<p>元素3</p>
</div>
<script>
//childNode系列==子节点系列
function test01(){
// 首先选中父亲节点
var divEle=document.querySelector('.root')
console.log(divEle)
// 选中父亲节点的所有节点 空白区域的text也算一个节点
console.log("divEle.childNodes:",divEle.childNodes)
/*divEle.childNodes:
NodeList(7) [ #text, p, #text, p, #text, p, #text ]
0: #text "\n "
1: <p>
2: #text "\n "
3: <p>
4: #text "\n "
5: <p>
6: #text "\n "
length: 7
*/
//选中父亲节点的第一个节点并打印在控制台
console.log(' divEle.firstChild :', divEle.firstChild)
//选中父亲节点的最后一个节点
console.log(' divEle.lastChild:', divEle.lastChild)
//选中元素一的标签P则是选中父亲节点的第一个子节点的兄弟节点
console.log("这是元素一的P标签",divEle.firstChild.nextSibling)//p
//选中元素三的标签p用lastchild
console.log("这是元素三的p标签",divEle.lastChild.previousSibling)
}
test01()
</script>
</body>
children:获取某一节点下所有的子一级元素节点
属性名称 | 描述 |
firstElementChild | 返回节点的第一个子节点,最普遍的用法是访问该元素的第一个子元素 |
lastElementChild | 返回节点的最后一个子节点 |
nextElementSibling | 下一个节点 |
previousElementSibling | 上一个节点 |
<body>
<div class="root">
<p>元素1</p>
<p>元素2</p>
<p>元素3</p>
</div>
<script>
//children===子元素节点系列
function test02(){
// 获取父节点的所有子元素节点
// var rootEle =document.getElementsByClassName('root')
// console.log("父节点元素",rootEle)
// console.log("root的节点类型",typeof(rootEle))
// for(var key in rootEle){
// console.log(rootEle[key].children)
// }
// console.log("root的子元素节点类型",typeof(rootEle.children))
// 用这个不行,这个子元素节点类返回的是undefined,用for-in循环遍历才行
console.log('…………………………………………………………………………………………………………………………………………………………')
var rootEle =document.querySelector('.root')
console.log("父节点元素",rootEle)
console.log("root的节点类型",typeof(rootEle))
//查询其所有子元素节点
console.log('子元素节点:',rootEle.children)
console.log(typeof("root的子元素节点类型",rootEle.children))
// 这个子元素节点类返回的是object
// 查询第一个子元素节点--------子元素一P
console.log("第一个子元素节点",rootEle.firstElementChild)
console.log(rootEle.firstElementChild.innerHTML)
// 查询第一个子元素节点--------子元素三P
console.log("最后一个子元素节点",rootEle.lastElementChild)
console.log(rootEle.lastElementChild.innerHTML)
// 查询第一个子元素节点的兄弟元素节点--------子元素二P
console.log("第二个子元素节点",rootEle.firstElementChild.nextElementSibling)
console.log(rootEle.firstElementChild.nextElementSibling.innerHTML)
// 查询最后一个子元素节点的兄弟元素节点--------子元素二P
console.log("第二个子元素节点",rootEle.lastElementChild.previousElementSibling)
console.log(rootEle.lastElementChild.previousElementSibling.innerHTML)
}
test02()
</script>
</body>
attributes:获取元素节点的所有属性节点
<body>
<div class="root">
<p>元素1</p>
<p>元素2</p>
<p>元素3</p>
</div>
<div class="content" id='now' name='test'>
hhhhhhhhaaaaa哈哈哈哈哈
</div>
<script>
function test03(){
// 获取类名为content的div标签
var testDiv=document.querySelector('.content')
console.log("testDiv.attributes获取content的所有属性",testDiv.attributes)
/* testDiv.attributes获取content的所有属性
NamedNodeMap(3) [ class="content", id="now", name="test" ]*/
}
test03()
</script>
</body>
2.非常规节点获取
获取html根节点:document.documentElement
获取body节点:document.body
获取head:document.head
<script>
function test04(){
//html根节点的获取
console.log(document.documentElement)
// body节点的获取
console.log(document.body)
// head节点的获取
console.log(document.head)
}
test04()
</script>
4.节点属性
nodeType | nodeName | nodeValue | |
元素节点 | 1 | 大写标签名 | null |
属性节点 | 2 | 属性名 | 属性值 |
文本节点 | 3 | #text | 文本内 |
<body>
<div class="root">
<p>元素1</p>
<p>元素2</p>
<p>元素3</p>
</div>
<div class="content" id='now' name='test'>
hhhhhhhhaaaaa哈哈哈哈哈
</div>
<script>
function test05(){
//获取元素节点
var divEle=document.querySelector('#now')
// 输出节点类型、名字和值
console.log(`节点类型:${divEle.nodeType},名字:${divEle.nodeName},值:${divEle.nodeValue}`)
//获取属性节点
var nameSrc=divEle.getAttributeNode('name')
console.log(nameSrc)
// 输出节点类型、名字和值
console.log(`节点类型:${nameSrc.nodeType},名字:${nameSrc.nodeName},值:${nameSrc.nodeValue}`)
//获取文本节点
var textnode=divEle.lastChild
// 输出节点类型、名字和值
console.log(`节点类型:${textnode.nodeType},名字:${textnode.nodeName},值:${textnode.nodeValue}`)
}
test05()
</script>
</body>
5. 操作DOM节点
1.创建节点
创建元素节点
createElement
创建文本节点·
createTextNode
创建属性节点
createAttribute
给元素节点设置属性节点
setAttributeNode
添加节点:
appendChild:向一个元素节点的末尾追加一个节点
insertBefore:向某一个节点前插入一个节点
删除节点:
removeChild:移除某一节点下的某一节点
remove:移除当前节点
替换节点:
replaceChild:将页面中的某一个节点替换
复制节点:
cloneNode(true|false)
true:复制节点包含节点下所有子节点
false:复制当前节点【默认】
<body>
<div class="root">
<p>元素1</p>
<p>元素2</p>
<p>元素3</p>
1
</div>
<div class="content" id='now' name='test'>
hhhhhhhhaaaaa哈哈哈哈哈
</div>
<script>
//实现节点的增删改复制
function test07(){
//创建节点p
var newp=document.createElement('p')
var newh2=document.createElement('h1')
//获取要操作的标签
var rootEle=document.querySelector('.root')
// 插入id=now的div里
rootEle.appendChild(newp).innerHTML='追加在最后的新元素'
rootEle.insertBefore(newp,rootEle.firstElementChild).innerHTML='在哪个元素前面的新元素'
// 删除rootdiv里的元素二
rootEle.removeChild(rootEle.firstElementChild.nextElementSibling.nextElementSibling)
// rootEle.firstElementChild.nextElementSibling.nextElementSibling.remove()
// 替换div里元素三的标签为p标签
newh2.innerHTML='不知道要写什么'
rootEle.replaceChild(newh2,rootEle.lastElementChild)
//复制节点
var start=rootEle.cloneNode()
var els=rootEle.cloneNode(true)
var end= rootEle.cloneNode(false)
console.log(start,els,end)
var idEle=document.querySelector('#now')
// 追加到#now里面看看
idEle.appendChild(start)
idEle.appendChild(els)
idEle.appendChild(end)
}
test07()
</script>
</body>
6.获取非行间样式【上一章已写过一种,这里主要是兼容性问题】
getComputedStyle【在非IE浏览器】
currentStyle【在IE浏览器】
7.获取元素的偏移量
offsetLeft、offsetTop:分两种情况
没有定位的情况:
获取元素边框外侧到页面内侧的距离
父盒子有定位的情况:
获取元素边框外侧到定位父级边框内侧的距离
offsetWidth、offsetHeight:获取元素内容宽高+padding宽高+border宽高的和
<!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;}
div{
width: 400px;
height: 400px;
background-color: skyblue;
margin: 100px;
padding: 50px;
position: relative;
}
div p{
width: 100px;
height: 100px;
background-color: 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>
</body>
</html>
8.获取元素尺寸宽高的三种方式
1.offsetWidth=内容 width+padding+border
2.clientWidth=内容 width+padding
3.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>元素尺寸</title>
<!-- -->
<style>
* {
padding: 0;
margin: 0;
}
div {
width: 200px;
height: 200px;
padding: 20px;
border: 10px solid pink;
margin: 100px;
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>
</body>
</html>
案例:
方式一用节点操作
<!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>
<!-- <li>css</li> -->
</ul>
</div>
<script>
/*
1. 详细描述需求
点击确定按钮,获取输入框内容,显示到ul节点下
分析: 复杂问题简化
1. 绑定点击事件
2. 获取输入框内容
3. 创建li子节点,输入框作用子节点文本内容,追加给ul
*/
var btn = document.querySelector('button')
btn.onclick = function(){
//2. 获取输入框内容
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 = ''
// 6. 绑定删除事件
onDelete()
}
/*
分析: 遍历所有li绑定点击事件, 删除当前点击的元素
*/
function onDelete(){
var liEles = document.querySelectorAll('ul>li') //能不能获取li
for(var i = 0; i < liEles.length; i++){
var liEle = liEles[i] //li元素
//绑定事件
liEle.onclick = function(){
// 删除当前点击的元素
// this关键字: 当前点击的元素节点对象
this.remove()
}
}
}
</script>
</body>
</html>
方式二:用数据操作
<!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>