节点操作
节点操作
Dom
节点
-
定义:
DOM
树内每一个内容都被称之为节点 -
类型
-
元素节点
-
所有的标签(如
body
、div
、p
等) -
html
是根节点
-
-
属性节点
- 所有的属性(如
src
、title
、class
等)
- 所有的属性(如
-
文本节点
- 所有的文本(包含文字、空格、换行等)
-
其他
-
一般的,节点至少拥有 nodeType
(节点类型)、nodeName
(节点名称)和 nodeValue
(节点值)这三个基本属性
查找节点
-
节点关系
-
父节点
子元素.parentNode
-
得到的是离元素最近的那个父级
-
找不到返回空
-
-
子节点
-
得到所有子节点,包括元素节点和文本节点
parentNode.childNodes
-
获取所有元素节点,不包括文本和注释
parentNode.children
注意:
返回的是一个伪数组,但不能使用
forEach
进行遍历 -
-
兄弟节点
-
兄弟节点(包括元素节点或文本节点等)
-
下一个兄弟节点
nextSibling
-
上一个兄弟节点
previousSibling
-
-
兄弟元素节点
-
下一个兄弟元素节点
nextElementSibling
-
上一个兄弟元素节点
previousElementSibling
-
-
-
增加节点
- 创建节点
let result = document.createElement('标签');
括号内填标签,需要加引号
创建完节点后,要对元素设置内容和样式
- 内容设置:
.innerHTML、.innerText
- 样式设置:
.classList、.style
-
添加节点
-
插入
node.insertBefore(child,指定元素)
node
为父级元素,child
为子级元素(或刚创建的元素节点)要求:
- 在父级元素的指定子元素前插入元素
- 如果不填指定元素则报错
- 如果找不到指定元素(如只填
null
)则默认是appendChild
的效果
-
追加
node.appendChild(child)
node
为父级元素,child
为子级元素(或刚创建的元素节点)要求:
- 在父级元素末尾追加元素,类似于
push
- 追加的节点可以是新创建的 也可以是页面上已经存在 (移动节点)
- 在父级元素末尾追加元素,类似于
-
-
克隆节点
用于需要创建一个复杂的标签,前提: 页面上有一个模板节点
node.cloneNode()
-
括号内为空或
false
,则为浅拷贝(即只复制标签,不复制里面的内容) -
括号内为
true
,则为深度拷贝(即既复制标签,又复制里面的内容)
与添加节点的区别:
添加节点的两个方法是移动式,即会把原节点从原来的地方删除,移动到指定位置;克隆则是克隆一个新的节点。
-
删除节点
-
通过父元素删除
parent.removeChild(child)
删除节点和隐藏节点(
display:none
) 有区别的: 隐藏节点还是存在的,但是删除,则从html
中删除节点注意:
如不存在父子关系则删除不成功,一定要是父子关系,不能爷爷删孙子。
-
自己删除自己
node.remove()
时间对象
用来表示时间的对象,可以得到当前系统时间
实例化
-
定义
在代码中发现了
new
关键字时,一般将这个操作称为实例化 -
获取方法
let date = new Date() console.log(date.getTime())
- 获取当前日期
let date = new Date()
- 获取指定日期
let date = new Date('2021-1-22')
- 获取当前日期
时间对象方法
获取日期对象的每一个部分 | 代码 |
---|---|
获取年 | getFullYear() |
获取月 | getMonth() + 1 |
获取日 | getDate() |
获取时 | getHours() |
获取分 | getMinutes() |
获取秒 | getSeconds() |
时间戳
-
定义
是指某一具体时间(如1970年01月01日00时00分00秒)至现在的毫秒数。
它是一种特殊的计量时间的方式。
-
获取方式
-
let date = new Date() console.log(date.getTime())
-
console.log(+new Date())
-
console.log(Date.now())
注意:
- 方法三只能得到当前的时间戳。
- 前面两种可以返回指定时间的时间戳,无需实例化。
总结
今日案例
学成在线数据渲染
- 说到渲染就会有数据和结构的参与,数据在
data.js
文件中,结构已经提供 - 渲染的本质就是:将数据生成动态结构的过程--本质就是以前的遍历拼接
- 遍历数据源,每个数据对象生成一个
li
标签 : 创建li元素,设置内容 - 将创建好的
li
标签追加到页面的指定结构中
let ul = document.querySelector('ul.clearfix')
// 循环遍历数组中的数据
data.forEach((element, index) => {
let li = document.createElement('li')
// 用模板字符串为创建好的li动态添加内容
li.innerHTML = `<img src="${data[index].src}" alt="" />
<h4>
${data[index].title}
</h4>
<div class="info">
<span>高级</span> • <span>${data[index].num}</span>人在学习
</div>`
// 渲染到页面上
ul.appendChild(li)
});
注意事项
这里容易犯一个错误,
li
必须是一个元素,才能用appendChild
语句添加到页面中,如果在给li
赋值时漏写了.innerHTML
或者在最后ul.appendChild(li)
括号中加了双引号,此时的li
变成了字符串,添加会报错。
Failed to execute 'insertBefore' on 'Node': >parameter 1 is not of type 'Node'.
微博发布与删除
需求1
- 注册
input
事件 - 将文本的内容的长度赋值给对应的数值
- 表单的
maxlength
属性可以直接限制在200个数之间
需求2
- 克隆预定义好的模板,将模板的
hidden
属性设置为false
, 并最终展示到页面上 - 判断如果内容为空,则提示不能输入为空, 并且直接
return
- 防止输入无意义空格, 使用字符串
.trim()
去掉首尾空格, 并将表单的value值设置为空字符串
需求3
- 获取文本域的内容, 赋值给由模板克隆出来的新标签里面的
content.innerText
- 随机获取数据数组里面的内容, 替换
newNode
的图片和名称 Math.random()* (n + 1)
利用时间对象将时间动态化
需求4
- 在事件处理函数里面获取点击按钮,注册点击事件 易错点: 必须在事件里面获取,外面获取不到
- 删除对应的元素 (通过this获取对应的那条需要删除的元素)
需求5
- 将表单域内容重置为空
- 将userCount里面的内容重置为0
-
封装好的时间函数
let dateFormat = function() { let date = new Date() let year = date.getFullYear() let month = date.getMonth() + 1 let day = date.getDate() let hour = date.getHours() let minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() let second = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() return `${year}-${month}-${day} ${hour}:${minute}:${second}` }
-
显示字数
let useCount = document.querySelector('.useCount') let txt = document.querySelector('textarea') txt.addEventListener('input', function() { let text = this.value useCount.innerHTML = text.trim().length }) txt.addEventListener('focus', function() { this.placeholder = `发个友善的评论见证当下~` }) txt.addEventListener('blur', function() { if (this.value.trim().length === 0) { this.placeholder = `不发也没关系,继续保持友善哦` } })
-
点击发布按钮发布微博,点击 X 号删除微博,如果为空弹出提示。
let list = document.querySelector('#list') let area = document.querySelector('#area') let useCount = document.querySelector('#useCount') let send = document.querySelector('#send') area.focus() send.addEventListener('click', function() { if (area.value === '') { alert('空的哦') return } let txt = area.value.trim() let index = parseInt(Math.random() * dataArr.length) let li = document.createElement('li') li.innerHTML = `<div class="info"> <img class="userpic" src="${dataArr[index].imgSrc}" /> <span class="username">${dataArr[index].uname}</span> <p class="send-time">发布于 ${dateFormat()}</p> </div> <div class="content">${txt}</div> <span class="the_del">X</span>` list.insertBefore(li, list.children[0]) let del = document.querySelector('.the_del') del.addEventListener('click', function() { del.parentNode.remove() }) area.value = '' useCount.innerHTML = 0 })
-
点击回车键发布微博,业务和点击发布按钮一样,因此可直接调用发布按钮的点击事件回调函数即可。
area.addEventListener('keydown', function(e) { if (e.key === 'Enter') { send.click() } })