JavaScript DOM 第三天

您所在的位置:网站首页 虚拟dom是什么意思啊 JavaScript DOM 第三天

JavaScript DOM 第三天

2023-03-28 14:15| 来源: 网络整理| 查看: 265

JavaScript DOM 第三天 01 节点操作 1.1 DOM节点

目标:能说出DOM节点的类型

DOM节点

DOM树里每一个内容都称之为节点

节点类型

元素节点

所有的标签 比如 body、 div html 是根节点

属性节点

所有的属性 比如 href

文本节点

所有的文本

其他

01.png

1.2 查找节点

目标:能够具备根据节点关系查找目标节点的能力

父节点查找:

parentNode 属性

返回最近一级的父节点 找不到返回为null

语法:

子元素.parentNode 复制代码

关闭二维码案例

需求:关闭二维码案例

分析:

需要给多个按钮绑定点击事件

关闭的是当前的父节点

x 复制代码 // 1. 获取元素,事件源为i,关闭的code let closeBtn = document.querySelector('.close-btn') let code = document.querySelector('.code') // 2. 事件监听 closeBtn.addEventListener('click', function () { // code隐藏 code.style.display = 'none' }) 复制代码

02.gif

子节点查找:

childNodes

获得所有子节点、包括文本节点(空格、换行)、注释节点等

children (重点)

仅获得所有元素节点 返回的还是一个伪数组

语法

父元素.children 复制代码

兄弟关系查找:

下一个兄弟节点

nextElementSibling 属性

上一个兄弟节点

previousElementSibling 属性

1.3 增加节点

目标:能够具备根据需求新增节点的能力

1.创建节点

即创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点

创建元素节点方法:

document.createElement('标签名') 复制代码

2.追加节点

要想在界面看到,还得插入到某个父元素中

插入到父元素的最后一个子元素:

父元素.appendChild(要插入的元素) 复制代码

插入到父元素中某个子元素的前面

父元素.insertBefore(要插入的元素, 在哪个元素前面) 复制代码

学成在线案例渲染

需求:按照数据渲染页面

分析:

准备好空的ul 结构

根据数据的个数,创建一个新的空li

li里面添加内容 img 标题等

追加给ul

let ul = document.querySelector('ul') // 1. 根据数据的个数,决定这小li的个数 for (let i = 0; i < data.length; i++) { // 2. 创建小li let li = document.createElement('li') // console.log(li) // 4. 先准备好内容,再追加 li.innerHTML = ` ${data[i].title} 高级 • ${data[i].num}人在学习 ` // 3. 追加给ul 父元素.appendChild(子元素) ul.appendChild(li) } 复制代码

03.png

特殊情况下,我们新增节点,按照如下操作:

复制一个原有的节点

把复制的节点放入到指定的元素内部

克隆节点

元素.cloneNode(布尔值) 复制代码

cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值

若为true,则代表克隆时会包含后代节点一起克隆

若为false,则代表克隆时不包含后代节点

默认为false

1.4 删除节点

目标:能够具备根据需求删除节点的能力

若一个节点在页面中已不需要时,可以删除它

在 JavaScript 原生DOM操作中,要删除元素必须通过父元素删除

语法

父元素.removeChild(要删除的元素) 复制代码

注:

如不存在父子关系则删除不成功

删除节点和隐藏节点(display:none) 有区别的: 隐藏节点还是存在的,但是删除,则从html中删除节点

02 时间对象

目标:掌握时间对象,可以让网页显示时间

时间对象:用来表示时间的对象

作用:可以得到当前系统时间

2.1 实例化

目标:能够实例化时间对象

在代码中发现了 new 关键字时,一般将这个操作称为实例化

创建一个时间对象并获取时间

获得当前时间

let date = new Date() 复制代码

获得指定时间

let date = new Date('1949-10-01') 复制代码 2.2 时间对象方法

目标:能够使用时间对象中的方法写出常见日期

因为时间对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式

方法作用说明getFullYear()获得年份获取四位年份getMonth()获得月份取值为 0 ~ 11getDate()获取月份中的每一天不同月份取值也不相同getDay()获取星期取值为 0 ~ 6getHours()获取小时取值为 0 ~ 23getMinutes()获取分钟取值为 0 ~ 59getSeconds()获取秒取值为 0 ~ 59

页面显示时间

需求:将当前时间以:YYYY-MM-DD HH:mm 形式显示在页面

分析:

调用时间对象方法进行转换

字符串拼接后,通过 innerText 给 标签

复制代码 // 1. 获取元素 let currentTime = document.querySelector('.current-time') // 防止空白 getTime() // 3. 实时 setInterval(getTime, 1000) function getTime() { // 1. 获取日期、时间 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() minute = minute >= 10 ? minute : '0' + minute let second = date.getSeconds() second = second >= 10 ? second : '0' + second // 2. 渲染内容 currentTime.innerHTML = `${year}年${month}月${day}日 ${hour}:${minute}:${second}` } 复制代码

04.gif

2.3 时间戳

目标:能够获得当前时间戳

什么是时间戳

是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式

三种方式获取时间戳

使用 getTime() 方法

// 1. 实例化 let date = new Date() // 2. 获取时间戳 console.log(date.getTime) 复制代码

简写 +new Date()

console.log(+new Date()) 复制代码

可以返回当前时间戳或者指定的时间戳

使用 Date().now()

console.log(Date().now()) 复制代码

无需实例化

但是只能得到当前的时间戳, 而前面两种可以返回指定时间的时间戳

毕业倒计时效果

需求:计算到下课还有多少时间

分析:

用将来时间减去现在时间就是剩余的时间 核心: 使用将来的时间戳减去现在的时间戳 把剩余的时间转换为 天 时 分 秒

注意:

通过时间戳得到是毫秒,需要转换为秒在计算

转换公式:

d = parseInt(总秒数/ 60/60 /24); // 计算天数 h = parseInt(总秒数/ 60/60 %24) // 计算小时 m = parseInt(总秒数 /60 %60 ); // 计算分数 s = parseInt(总秒数%60); // 计算当前秒数 复制代码 // 防止空白 let gruduateTime = +new Date('2023-6-28 00:00:00') changeTime() setInterval(changeTime, 1000) function changeTime() { // 1. 获取时间戳 let currentTime = +new Date() // 2. 计算剩余秒数 let millisecond = (gruduateTime - currentTime) / 1000 // 3. 转换时间 let day = parseInt(millisecond / 60 / 60 / 24) day = day < 10 ? '0' + day : day let hour = parseInt((millisecond / 60 / 60) % 24) let minute = parseInt((millisecond / 60) % 60) minute = minute < 10 ? '0' + minute : minute let second = parseInt(millisecond % 60) second = second < 10 ? '0' + second : second // 4. 渲染内容 // 获取元素 let showDay = document.querySelector('.title') let showHour = document.querySelector('#hour') let showMinute = document.querySelector('#minute') let showSecond = document.querySelector('#second') showDay.innerHTML = `毕业倒计时 ${day}天` showHour.innerHTML = hour showMinute.innerHTML = minute showSecond.innerHTML = second } 复制代码

05.gif

03 综合案例

发布微博案例

需求1

注册input事件

将文本的内容的长度赋值给对应的数值

表单的maxlength属性可以直接限制在200个数之间

需求2

克隆预定义好的模板,将模板的hidden属性设置为false, 并最终展示到页面上

判断如果内容为空,则提示不能输入为空, 并且直接return

防止输入无意义空格, 使用字符串.trim()去掉首尾空格, 并将表单的value值设置为空字符串

需求3

获取文本域的内容, 赋值给由模板克隆出来的新标签里面的content.innerText

随机获取数据数组里面的内容, 替换newNode的图片和名称

利用时间对象将时间动态化 new Date().toLocaleString()

需求4

在事件处理函数里面获取点击按钮,注册点击事件(易错点: 必须在事件里面获取,外面获取不到)

删除对应的元素 (通过this获取对应的那条需要删除的元素)

需求5

将表单域内容重置为空

将userCount里面的内容重置为0

0 / 200 发布 死数据:百里守约 死数据:发布于 2020年12月05日 00:07:54 死数据:111 X 复制代码 // 需求1:检测用户输入字数 // 1. 注册input事件 // 2. 将文本的内容的长度赋值给对应的数值 // 3. 表单的maxlength属性可以直接限制在200个数之间 let textarea = document.querySelector('textarea') let useCount = document.querySelector('.useCount') // 发布按钮 let send = document.querySelector('#send') // ul let ul = document.querySelector('#list') textarea.addEventListener('input', function () { // console.log(this.value.length) useCount.innerHTML = this.value.length }) // 需求2: 输入不能为空 // 点击button之后判断 // 判断如果内容为空,则提示不能输入为空, 并且直接return 不能为空 // 防止输入无意义空格, 使用字符串.trim()去掉首尾空格 // console.log(' str') // console.log(' str '.trim()) // 并将表单的value值设置为空字符串 // 同时下面红色为设置为0 send.addEventListener('click', function () { if (textarea.value.trim() === '') { // 并将表单的value值设置为空字符串 textarea.value = '' // 同时下面红色为设置为0 useCount.innerHTML = 0 return alert('内容不能为空') } // 随机数 function getRandom(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min } let random = getRandom(0, dataArr.length - 1) // 需求3: 新增留言 写到send 的里面 // 创建一个小li,然后里面通过innerHTML追加数据 let li = document.createElement('li') // 随机获取数据数组里面的内容, 替换newNode的图片和名字以及留言内容 li.innerHTML = ` ${dataArr[random].uname}

${new Date().toLocaleString()}

${textarea.value} X ` // 需求4:删除留言 放到追加的前面 // 在事件处理函数里面获取点击按钮, 注册点击事件 // (易错点: 必须在事件里面获取, 外面获取不到) // 删除对应的元素(通过this获取对应的那条需要删除的元素) // 教你一招: 放到追加进ul的前面,这样创建元素的同时顺便绑定了事件,赞~~ // 使用 li.querySelector() let del = li.querySelector('.the_del') del.addEventListener('click', function () { // 删除操作 点击的是X 删除的小li 父元素.removeChild(子元素) ul.removeChild(li) }) // 利用时间对象将时间动态化 new Date().toLocaleString() // 追加给 ul 用 父元素.insertBefore(子元素, 那个元素的前面) ul.insertBefore(li, ul.children[0]) // 需求5:重置 // 将表单域内容重置为空 // 将userCount里面的内容重置为0 textarea.value = '' // 同时下面红色为设置为0 useCount.innerHTML = 0 }) 复制代码

06.gif

04 重绘和回流 4.1 浏览器是如何进行界面渲染的 07.png

解析(Parser)HTML,生成DOM树(DOM Tree)

同时解析(Parser) CSS,生成样式规则 (Style Rules)

根据DOM树和样式规则,生成渲染树(Render Tree)

进行布局 Layout(回流/重排):根据生成的渲染树,得到节点的几何信息(位置,大小)

进行绘制 Painting(重绘): 根据计算和获取的信息进行整个页面的绘制

Display: 展示在页面上

4.2 概念

回流(重排)

当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为 回流。

重绘

由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、outline等), 称为重绘。

重绘不一定引起回流,而回流一定会引起重绘。

会导致回流(重排)的操作:

页面的首次刷新

浏览器的窗口大小发生改变

元素的大小或位置发生改变

改变字体的大小

内容的变化(如:input框的输入,图片的大小)

激活css伪类 (如::hover)

脚本操作DOM(添加或者删除可见的DOM元素)

简单理解影响到布局了,就会有回流

思考下述代码的重绘重排过程!

let s = document.body.style s.padding = '2px' // 重排 + 重绘 s.border = '1px solid red' // 再一次 重排 + 重绘 s.color = 'blue' // 再一次 重绘 s.backgroundColor = '#ccc' // 再一次 重绘 s.fontSize = '14px' // 再一次 重排 + 重绘 复制代码


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3