DOM-节点操作
节点操作
一、DOM节点
本质:在DOM树中的每一个内容,都叫做节点
二、节点类型
元素节点
1.所有的标签:body、div
2.html是根节点
属性节点
所有的属性,如 href
文本节点
所有的文本
三、查找节点
思考:关闭二维码的案例中,当我们点击DIV中的I标签关闭按钮,关闭的是整个DIV。那么这个I和DIV是什么关系?
结论:是父子二代关系
引出:查找节点,点击关闭按钮直接关闭它爹,就不用再获取DIV的DOM元素了。
节点的关系:
1.父节点
语法:子元素.parentNode
作用:返回最近一级父节点,找不到返回NULL
关闭多个二维码案例
<script>
let span = document.querySelectorAll(`.close`)
for (let index = 0; index < span.length; index++) {
span[index].addEventListener(`click`,function(){
this.parentNode.style.display = `none`
})
}
</script>
解题思路:
1.获取元素
2.给所有span事件声明(遍历FOR循环)
3.我自己的父元素 设置样式需求
2.子节点
语法:父元素.children / .childNodes
区别:
1.childNodes 获取的是所有子节点,包括文本节点(空格,换行)注释等
2.children (重点):仅获得所有元素子节点,返回的还是伪数组
<script>
let ul =document.querySelector(`ul`)
// 什么都拿包括文本 空格 等等 了解
console.log(ul.childNodes)
console.log(ul.children);//拿子节点
</script>
关闭大盒子案例
<script>
// 获取所有UL 数组
let ul= document.querySelectorAll(`ul`)
for (let index = 0; index < ul.length; index++) {
ul[index].addEventListener(`click`,function(){
// 拿到 所有子元素 还是数组
for (let index = 0; index < this.children.length; index++) {
this.children[index].style.display = `none` //表示每一个LI
}
})
}
</script>
解题思路:
1.首先确认获取的元素,多个UL ,用all
2.遍历所有UL 声明事件
3.因为要拿到UL中的子元素 还是数组 继续 遍历
4.取得遍历的子元素进行样式设置
3.兄弟节点
语法:
1.nextElementSibling 属性 下一个兄弟节点
2.previousElementSibling 属性 上一个兄弟节点
兄弟节点小案例
<script>
/*
1.获取所有LI 数组
2.遍历 绑定事件
3.事件触发 this.next this.pre 获取对于元素
*/
let lis = document.querySelectorAll(`li`)
for (let index = 0; index < lis.length; index++) {
lis[index].addEventListener(`click`,function(){
// 上一个 设置
this.previousElementSibling.style.backgroundColor = `blue`
// 下一个 设置
this.nextElementSibling.style.backgroundColor = `green`
})
}
</script>
四、增加节点
1.创建节点
本质:创建出一个新的网页元素,是添加在内存中的。
语法:document.createElement(“标签名”)
2.插入(追加)节点
本质:想要在页面中看到,还要插入到某个父元素中
语法:
1.插入到父元素最后一个子元素 父元素.appendChild(要插入的元素)
2.插入到父元素中某个子元素前 父元素.inserBefore(要插入的元素,在那个元素前面)
<script>
// 创建一个 li标签 节点
let li = document.createElement(`li`)
// 此时是看不见的,是放在内存当中,想要看得见 插入父元素中
let ul = document.querySelector(`ul`)
ul.appendChild(li) //把Li 插入到ul中
li.innerText = `我是追加进来的`
li.style.backgroundColor = `red`
// 插入的节点会在父元素的底部
</script>
追加的补充知识点
对于appendChild而言
1.如果改元素已经存在网页中,作用类似 移动
2.如果该元素是新创建的,作用类似 简单的插入
<script>
let li = document.querySelector(`.left li:nth-child(2)`)
let right = document.querySelector(`.right`)
li.addEventListener(`click`,function(){
right.appendChild(li)
</script>
对于inserBefore而言
1.如果要插入的元素已经存在,作用 也是移动
2.如果要插入元素是新创建的, 作用 插入
<script>
let li =document.querySelector(`.left li:nth-child(3)`)
let li2 =document.querySelector(`.right li:nth-child(2)`)
let right = document.querySelector(`.right`)
li.addEventListener(`click`,function(){
right.insertBefore(li,li2)
})
</script>
菜单移动案例
<script>
let lis = document.querySelectorAll(`.cai li`)
let cai = document.querySelector(`.cai1`)
for (let index = 0; index < lis.length; index++) {
lis[index].addEventListener(`click`,function() {
cai.appendChild(lis[index])
})
}
</script>
菜单移动案例进阶(了解)
<script>
let lis = document.querySelectorAll(`.cai li`)
let cai1 = document.querySelector(`.cai1`)
let cai = document.querySelector(`.cai`)
let parent
for (let index = 0; index < lis.length; index++) {
lis[index].addEventListener(`click`,function(){
if(this.parentNode !== cai1){
parent = cai1
}
if (this.parentNode !== cai){
parent =cai
}
parent.appendChild(this)
})
}
</script>
学成在线(第二种方式-VUE底层原理)
使用创建和添加节点的方式
<script>
let ul =document.querySelector(`.clearfix`)
for (let index = 0; index < data.length; index++) {
let li = document.createElement(`li`)
let img = document.createElement(`img`)
img.src = data[index].src
let h4 = document.createElement(`h4`)
h4.innerText = data[index].title
let div = document.createElement(`div`)
// 这里不用加点号
div.classList.add(`info`)
let span1 =document.createElement(`span`)
span1.innerText = `高级`
let span2 =document.createElement(`span`)
span2.innerText=data[index].num
let txt1 = document.createTextNode(` • `)
let txt2 = document.createTextNode(`人在学习`)
li.append(img,h4,div)
div.append(span1,txt1,span2,txt2)
ul.appendChild(li)
}
</script>
解题思路:
1.首先要获取数组中数据 遍历数组 拿到所有数据
2.创建LI标签
3.创建LI标签内的标签
4.把标签插入到对应的结构当中
5.最后创建文本节点,把两个文本内容也插入到对应结构当中
知识补充:
1.append可以插入多个标签
2.appendChild插入一个
回顾之前代码:
<script>
let html = `<div class="box w">
<div class="box-hd">
<h3>精品推荐</h3>
<a href="#">查看全部</a>
</div>
<div class="box-bd">
<ul class="clearfix">`
for (let index = 0; index < data.length; index++) {
html +=`<li>
<img src="${data[index].src}" alt="" />
<h4>${data[index].title}</h4>
<div class="info"><span>高级</span> • <span>${data[index].num}</span>人在学习</div>
</li>`
}
html += `</ul></div></div>`
document.write(html)
</script>
克隆节点
本质:复制一个烟油的节点,把复制的节点放入到指定的元素内部
语法:元素.cloneNode(布尔值)
细节:
1.布尔为true,表示会克隆 后代一起 (深拷贝)
2.布尔为false,表示克隆 不包括后代 (浅克隆)
3.默认为false
4.直接let 一个元素 因为是克隆所以可以不创建新元素
<script>
let box = document.querySelector(`.box`)
// 克隆不用创建新的标签
// let box1 = document.createElement(`div`)
let box1 = box.cloneNode(true) //深克隆 会把后代也克隆
// box1 = box.cloneNode(false) //浅克隆 不会克隆后代
document.body.appendChild(box1)
</script>
五、删除节点
本质:若一个节点在页面中不需要,就可以删除它
语法:元素.removeChild (需要由父元素执行删除操作)
<script>
let btn = document.querySelector(`button`)
let ul = document.querySelector(`ul`)
// 写在外面 只是获取第一个li 删除了就不会再删除了
// let li = document.querySelector(`li:nth-child(1)`)
btn.addEventListener(`click`,function(){
//写在里面 每点击一次,就删除第一个LI
let li = document.querySelector(`li:nth-child(1)`)
ul.removeChild(li)
})
</script>
细节:
1.如过不存在父子关系删除不成功
2.删除和隐藏节点区别在于 删除已经不存在了,隐藏节点还存在
3.在事件内获取元素和全局获取 性质可能不同
时间对象
本质:用来表示时间的对象
作用:可以得到当前动态的系统时间
一、实例化
本质:在代码中发现了new关键字时,一般称这个操作为实例化
作用:创建一个时间对象并获取时间
语法:
1.获取当前时间:let date = new Date()
2.获取指定时间:let date = new Date(”2022-4-7“)
二、时间对象方法
作用:时间对象返回的数据我们不能直接使用,所以需要转换成世纪开发中的常用的格式
时间小案例
<script>
setInterval(function(){
let date = new Date()
let year = date.getFullYear()
let mon = date.getMonth()+1
mon=mon>10?mon:`0`+mon
let date1 = date.getDate()
date1=date1>10?date1:`0`+date1
let hours = date.getHours()
let min = date.getMinutes()
let sec= date.getSeconds()
let time =`${year}年${mon}月${date1}日${hours}时${min}分${sec}秒`
h1.innerText = time
},1000)
</script>
三、时间戳
本质:是指1970年01月01日00分00秒起止到现在的毫秒数,是一种特殊的计量时间的方式
获取方式:
<script>
let date = new Date()
console.log(date.getTime()); //第一种方式
console.log(+new Date()); // 第二种方式
console.log(Date.now()); // 第三种方式
</script>
作用:快速生成一个不会重复的数字 配合随机数
注意点:第三种方式,只能得到当前的时间戳,前面两种可以返回指定时间的时间戳
综合案例
初步代码
<script>
let ul = document.querySelector(`#list`)
let span = document.querySelector(`.useCount`)
let area = document.querySelector(`#area`)
let btn = document.querySelector(`#send`)
let date = new Date()
area.addEventListener(`input`,function(){
let value = area.value.length
span.innerText = value
})
btn.addEventListener(`click`,function(){
// 如果文本框不等于0,才执行代码
if(area.value.length!==0){
let index = Math.round( Math.random()*(dataArr.length-1) )
let li = document.createElement(`li`)
let div1=document.createElement(`div`)
div1.classList.add(`info`)
let img = document.createElement(`img`)
img.classList.add(`userpic`)
img.src=dataArr[index].imgSrc
let span1 = document.createElement(`span`)
span1.classList.add(`username`)
span1.innerText=dataArr[index].uname
let p = document.createElement(`p`)
p.classList.add(`send-time`)
p.innerText=`发布于${time}`
let div2 = document.createElement(`div`)
div2.innerText=area.value
div2.classList.add(`content`)
let span2 = document.createElement(`span`)
span2.innerText=`X`
span2.classList.add(`the_del`)
li.append(div1,div2,span2)
div1.append(img,span1,p)
ul.appendChild(li)
area.value=``
span.innerText=0
span2.addEventListener(`click`,function(){
// this.parentNode.style.display = `none`
ul.removeChild(li)
})
}
})
// 时间对象函数
function getTime() {
let date = new Date()
let year = date.getFullYear()
let mon = date.getMonth()+1
mon = mon>10 ? mon : `0`+mon
let date1 = date.getDate()
date1 = date1>10 ? date1 : `0`+date1
let hours = date.getHours()
hours = hours>10 ? hours : `0`+hours
let min = date.getMinutes()
min = min>10 ? min : `0`+min
let sec = date.getSeconds()
sec = sec>10 ? sec : `0`+sec
let time =`${year}-${mon}-${date1} ${hours}:${min}:${sec}`
return time
}
let time = getTime()
console.log(time)
</script>
解题思路:
1:明确需求 分步骤
2.确定点击事件 (事件案例)
3.点击事件内 创建和插入标签(今日所学)
4.随机提取数组中对象元素 (随机提取数组案例)
5.时间对象封装函数 (今日所学)
6.文本框字符串长度跟随变化 清空等小代码补充 (昨日案例)
优化后代码
<script>
let ul = document.querySelector(`#list`)
let span = document.querySelector(`.useCount`)
let area = document.querySelector(`#area`)
let btn = document.querySelector(`#send`)
let date = new Date()
area.addEventListener(`input`,function(){
let value = area.value.length
span.innerText = value
})
btn.addEventListener(`click`,function(){
// 如果文本框不等于0,才执行代码
if(area.value.length!==0){
let index = Math.round( Math.random()*(dataArr.length-1) )
let lihtml = `<li>
<div class="info">
<img class="userpic" src="${dataArr[index].imgSrc}" />
<span class="username">${dataArr[index].uname}</span>
<p class="send-time">发布于 ${time}</p>
</div>
<div class="content">${area.value}</div>
</li>`
ul.innerHTML += lihtml
area.value=``
span.innerText=0
}
})
// 时间对象函数
function getTime() {
let date = new Date()
let year = date.getFullYear()
let mon = date.getMonth()+1
mon = mon>10 ? mon : `0`+mon
let date1 = date.getDate()
date1 = date1>10 ? date1 : `0`+date1
let hours = date.getHours()
hours = hours>10 ? hours : `0`+hours
let min = date.getMinutes()
min = min>10 ? min : `0`+min
let sec = date.getSeconds()
sec = sec>10 ? sec : `0`+sec
let time =`${year}-${mon}-${date1} ${hours}:${min}:${sec}`
return time
}
let time = getTime()
console.log(time)
</script>
解题思路:
1.明确需求 分步骤
2.确定点击事件
3.运用HTML插入JS的+=拼接法
4.随机提取数组中对象元素 (随机提取数组案例)
5.时间对象封装函数 (今日所学)
6.文本框字符串长度跟随变化 清空等小代码补充 (昨日案例
总结:
主要点在于创建和插入标签结构今日所学的时间对象,创建和插入节点的方法,配合昨日的微博案例做拼装。重点在于需求的分析和分解,需要了解大体结构,从静态入手,再解决动态需求。
优化的代码是基于初步代码的底层原理而来的,所以需要都理解。