第三天WebAPI
DOM节点
- DOM树里每一个内容都称之为节点
- 节点类型
节点类型 | 描述 |
---|---|
元素节点 | 所有的标签 比如 body、 div 。html 是根节点 |
属性节点 | 所有的属性 比如 href src |
文本节点 | 比如标签里面的文字 |
我们重点记住那个节点?
- 元素节点
可以更好的让我们理清标签元素之间的关系
节点关系
父节点 ,子节点 ,兄弟节点、
查找节点
目标:能够具备根据节点关系查找目标节点的能力
父节点查找:
parentNode 属性 , 返回最近一级的父节点 找不到返回为null
子元素.parentNode
代码示例
<div>
<button>目标元素</button>
<h1>好</h1>
</div>
<script>
let span = document.querySelector('button');
let h1 =document.querySelector('h1');
// 先获取button 目标元素
console.dir(button);
// 获取父元素的div标签
console.dir(button.parentNode);
h1.parentNode.style.display='blok'
button.parentNode.style.display="none"
</script>
</body>
关闭二维码案例
需求:多个二维码,点击谁,谁关闭
分析:
①:需要给多个按钮绑定点击事件
②:关闭的是当前的父节点
<script>
/*
1 先处理好静态结构
2 先获取到关闭按钮 数组
3 遍历数组 给关闭按钮 绑定 点击事件
4 事件触发了
通过 this 获取到 对应的父元素 隐藏
*/
let closeBtns =document.querySelectorAll('.close-btn');
// 遍历
for(let index =0; index <closeBtns.length;index++){
// 绑定点击事件
closeBtns[index].addEventListener('click',function(){
// this 获取到对应的父元素 隐藏
// this.parentNode.style.display="none"
// document.parentNode
// document.body.style.display='none';
// document.parentNode
// document.body.style.display="none"
this.parentNode.style.display="none"
})
}
</script>
子节点查找:
关键字childNodes 获得所有子节点、包括文本节点(空格、换行)、注释节点等
children (重点) 仅获得所有元素节点 , 返回的还是一个伪数组
语法:父元素.children
代码示例
<script>
/*
1 获取到所有的ul标签 数组
2 遍历ul数组 挨个绑定点击事件
3 点击事件触发了
1 this = 当前被点击的ul标签
2 this.children 获取到 所有的ul的子元素 数组
3 遍历 children 获取到中的每一个li标签
4 li.style.display="none"
*/
// 获取扫所有的ul标签 数组
let uls =document.querySelectorAll('ul')
// 点击事件触发
for(let index=0;index<uls.length;index++){
//
uls[index].addEventListener('click',function(){
for(let j=0;j<this.children.length;j++){
this.children[j].style.display="none"
}
})
}
</script>
兄弟关系查找:
下一个兄弟节点 nextElementSibling 属性
上一个兄弟节点 previousElementSibling 属性
代码示例
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
<script>
/* 1.获取所有的li标签 数组
2.遍历 绑定点击事件
3.事件触发了
4.this.text
this.previou 获取到对应的元素 设置他们的样式
*/
// 1 获取所有的li标签 数组
let lis = document.querySelectorAll('li');
// 2. 遍历绑定点击事件
for(let index =0;index< lis.length;index++){
// 3.事件触发
lis[index].addEventListener('click',function(){
/* 上一个行动 */
this.previousElementSibling.style.backgroundColor='blue'
// 下一个兄弟
this.nextElementSibling.style.backgroundColor="green"
})
}
</script>
增加节点
能够具备根据需求新增节点的能力
1.创建一个新的节点
把创建的新的节点放入到指定的元素内部
创建元素节点方法:
document.createElement('标签名');
2.追加节点
要想在界面看到,还得插入到某个父元素中
插入到父元素的最后一个子元素:
父元素.appendChild(要插入的元素)
插入到父元素中某个子元素的前面
父元素.insertBefore(要插入的元素,在哪个元素前面)
放在dom元素的内部的末尾
dom.insertBefore(要插入的元素,目标元素的位置);
要插入到dom元素的一个子元素(目标元素的位置)的上面
<ul class="left">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
<ul class="right">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
/*
1.insertBefore 也能插入元素 功能也类似 appendChild
1 如果要插入的元素 是已经存在的 那么insertBefore作用 移动
2 如果要插入的元素 是新创建的 insertBefore作用 仅仅 插入
*/
//
let a=document.querySelector('.left li:nth-child(1)');
let two = document.querySelector('.right li:nth-child(3)');
let right = document.querySelector('.right');
let li =document.createElement('li');
li.innerText="新创建";
right.insertBefore(li,two);
// 父元素.insertBefore(要插入的元素,哪个元素的上面)
</script>
新增节点
1.创建一个标签
document.createElement(标签名);
2.插入标签
dom.appendChild(要插入的元素); 注意:只能插入一个标签 ,插入多个标签:dom.append();
<script>
// 1.创建一个 li标签 节点
let lis= document.createElement('li');
lis.innerText='这个是新创建的节点';
lis.style.backgroundColor="green"
//
let ul =document.querySelector('ul');
// 增加背景颜色
ul.appendChild(lis);
console.log(lis);
</script>
案例
购物车数量改变
需求:用户点击加号,则文本框+1,点击减号,则文本框-1,如果文本框为1,则禁用减号
①:给添加按钮注册点击事件, 获取表单的value,然后自增
②:解除减号的disabled状态
③:给减号按钮添加点击事件,获取表单的value,然后自减
④:自减结束需要判断,如果结果小于等于1 则添加上disabled状态
代码图
<span>1</span>
<button class="increment">+</button>
<button disabled class="decrement">-</button>
<script>
/* 1.获取标签
2.分别绑定了点击事件
3.+业务 只需要 对 数量做增加即可
4.-业务 判断 如果数量等于1 那么就需要禁用按钮 */
let span =document.querySelector("span");
let increment =document.querySelector('.increment');
let decrement =document.querySelector('.decrement')
// 增加
increment.addEventListener('click',function(){
// console.log('+');
span.innerText++;
// 不禁用
decrement.disable=false;
})
// 减少
decrement.addEventListener('click',function(){
console.log('-');
decrement.disable=true;
})
</script>
排他思想
<script>
// 先获取到每一个li标签
// 再li标签绑定点击事件
// 写处理其他所有的元素 让让他们的背景颜色都变成白色
// 事件触发 设置 被点击的li标签 选中的样式
let liList =document.querySelectorAll('li');//获所有的li标签 数组
console.log(liList);
for(let index=0;index< liList.length;index++){
// 对所有的li 标签开始绑定事件
liList[index].addEventListener('click',function(){
// 对所有的li标签,并开始绑定点击事件
setAllLiColor();
this.style.backgroundColor="red";
})
}
// 设置所有li标签的背景颜色为白色
function setAllLiColor(){
// 遍历数组
for(let j =0;j<liList.length;j++){
// 背景色为白色
liList[j].style.backgroundColor="#fff";
}
}
</script>
插入节点
appendChild 只能插入一个元素
append 插入多个元素
insertBeforo
克隆节点
复制一个原有的节点
把复制的节点放入到指定的元素内部
cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值
若为true,则代表克隆时会包含后代节点一起克隆–深拷贝
若为false,则代表克隆时不包含后代节点–浅拷贝
默认为false
<div class="box">
<button>点击</button>
</div>
<script>
let box =document.querySelector('.box');
let newBox =box.cloneNode();//浅克隆 不会吧 div 的后代节点一起克隆
let newBox1 =box.cloneNode(true); //true 深克隆 会把div的后代节点一起克隆
document.body.append(newBox,newBox1);
</script>
数组和伪数组
数组和伪数组都可以使用for循环
伪数组对于好用的数组的方法 不支持(filter,map,some,every,find,findIndex,reduce)
使用document.querySelecctorAll 获取数组 伪数组
时间对象
掌握时间对象,可以让网页显示时间
时间对象:用来表示时间的对象
作用:可以得到当前系统时间
实例化 时间对象方法 时间戳
实例化
在代码中发现了 new 关键字时,一般将这个操作称为实例化
创建一个时间对象并获取时间
获得当前时间
let date = new Date();
获得指定时间
let date = new Date('1933-03-1')
时间对象方法
能够使用时间对象中的方法写出常见日期
因为时间对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式
方法 | 作用 | 说明 |
---|---|---|
getFullYear() | 获得年份 | 获取四位年份 |
getMonth() | 获得月份 | 取值为 0 ~ 11 |
getDate() | 获取月份中的每一天 | 不同月份取值也不相同 |
getDay() | 获取星期 | 取值为 0 ~ 6 |
getHours() | 获取小时 | 取值为 0 ~ 23 |
getMinutes() | 获取分钟 | 取值为 0 ~ 59 |
getSeconds() | 获取秒 | 取值为 0 ~ 59 |
页面显示时间
需求:将当前时间以:YYYY-MM-DD HH:mm 形式显示在页面
①:调用时间对象方法进行转换
②:字符串拼接后,通过 innerText 给 标签
<h1></h1>
<script>
// 在定时器内输出它 年 月 日 是分秒
// 时间函数
function times(){
// 时间对象
let date =new Date();
let year = date.getFullYear(); //年
let month =date.getMonth()+1; //月
let d =date.getDate(); //日
let day =date.getDay();//星期几
let h =date.getHours(); //小时
let m =date.getMinutes();//分
let s =date.getSeconds();//秒
if(s<10){
s='0'+s
}else if(m<10){
m='0'+m
}
let times =document.querySelector('h1');
times.innerHTML=`显示时间${year}年${month}月${d}日星期${day}: ${d}:${m}:${s}`;
}
setInterval(times,1000)
</script>
时间戳
什么是时间戳
是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式
来快速生成一个不会重复的数组 * 随机数
三种方式获取时间戳
1.使用 getTime() 方法
//1.实例化
let date =new Date()
//获取时间戳
console.log(date.getTime())
2… 简写 +new Date()
只有日期对象可以使用+ 转成时间戳
console.log(+new Date())
3.使用 Date.now()
console.log(Date.now())
毕业倒计时效果
![1649314079657](day03(Dom节点).assets/1649314079657.png)
需求:计算到下课还有多少时间
①:用将来时间减去现在时间就是剩余的时间
②:核心: 使用将来的时间戳减去现在的时间戳
③:把剩余的时间转换为 天 时 分 秒
注意:
通过时间戳得到是毫秒,需要转换为秒在计算
转换公式
d = parseInt(总秒数/ 60/60 /24);
d = parseInt(总秒数/ 60/60 /24);
m = parseInt(总秒数 /60 %60 );
s = parseInt(总秒数%60);
<div class="countdown">
<p class="next">今天是2021年8月28日</p>
<p class="title">下班倒计时</p>
<p class="clock">
<span id="hour">00</span>
<i>:</i>
<span id="minutes">00</span>
<i>:</i>
<span id="scond">00</span>
</p>
<p class="tips">
现在是18:30:00
</p>
</div>
<script>
// 获取元素
let hours = document.querySelector('#hour');
let minutes = document.querySelector('#minutes');
let scond = document.querySelector('#scond');
console.log(hours,minutes,scond);
// 时间id
let timeId = setInterval(function(){
// 1.获取下课时间离当前日期的时间戳
// 1.1获取下课时间的时间戳
let date =new Date('2022-4-7 21:30:00');
console.log(date);
// 1.2 获取当前日期的时间戳
let now =Date.now();
console.log(now);
// 1.3 获取差异
let offset =parseInt((date.getTime()-now)/1000)
console.log(offset);
// 判断结束
if(offset ===0){
clearInterval(timeId);
}
// 将时间间隔转换为时分秒
let hour =parseInt(offset/60/60);
hour = hour<10 ? '0'+hour : hour
let minute =parseInt((offset%3600)/60);
minute = minute < 10 ? '0' + minute : minute
let second =parseInt(offset%60);
second = second < 10 ? '0' + second : second
hours.innerHTML =hour
minutes.innerHTML=minute
scond.innerHTML=second
},1000);
</script>
学成在线案例渲染
需求:按照数据渲染页面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PtkstqqA-1649426039240)(day03(Dom节点).assets/学成在线.png)]
代码图
<!-- 1 引入 要显示的数据 -->
<script src="./data/data.js"></script>
<!-- 2 在写自己的业务 -->
<script>
/*
1 获取到要渲染到页面中的数据 data
2 遍历data
要求使用 createElement appendChild 来往ul中插入 li 元素
1 创建一个li标签
2 创建一个图片便签 设置 src属性
3 创建一个h4标签 设置文本内容
4 创建一个div标签 添加一个class info
5 创建两个span标签
1个设置内容 高级
2个设置人数 1125
6 组装
li标签要 插入 img
li标签要 插入 h4
li标签要 插入 div.info
div.info 要插入两个span
ul插入 li
3 append可以插入多个元素 appendChild 只能插入一个元素
createTextNode 创建文件节点
*/
let ul = document.querySelector('.list');
for (let index = 0; index < data.length; index++) {
// const element = data[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 text1 = document.createTextNode(' • ');
let text2 = document.createTextNode('人在学习');
// 节点的类型 元素节点(标签)、文本节点
// 开始组装 append 可以同时插入多个标签
// appendChild 只能插入一个标签
div.append(span1, text1, span2, text2);
li.append(img, h4, div);
// li.append()
ul.appendChild(li);
}
</script>
发布微博案例
<div class="w">
<div class="controls">
<img src="images/tip.png" alt="" /><br />
<textarea
placeholder="说点什么吧..."
id="area"
cols="30"
rows="100"
maxlength="200"
></textarea>
<div>
<span class="useCount">0</span>
<span>/</span>
<span>200</span>
<button id="send">发布</button>
</div>
</div>
<div class="contentList">
<ul id="list">
<!-- <li>
<div class="info">
<img class="userpic" src="./images/9.5/06.jpg" />
<span class="username">张良</span>
<p class="send-time">发布于 2022-4-7 15:12:23</p>
</div>
<div class="content">sdfdf</div>
<span class="the_del">X</span>
</li> -->
</ul>
</div>
</div>
<script>
let dataArr = [
{
uname: '司马懿',
imgSrc: './images/9.5/01.jpg',
},
{
uname: '女娲',
imgSrc: './images/9.5/02.jpg',
},
{
uname: '百里守约',
imgSrc: './images/9.5/03.jpg',
},
{
uname: '亚瑟',
imgSrc: './images/9.5/04.jpg',
},
{
uname: '虞姬',
imgSrc: './images/9.5/05.jpg',
},
{
uname: '张良',
imgSrc: './images/9.5/06.jpg',
},
{
uname: '安其拉',
imgSrc: './images/9.5/07.jpg',
},
{
uname: '李白',
imgSrc: './images/9.5/08.jpg',
},
{
uname: '阿珂',
imgSrc: './images/9.5/09.jpg',
},
{
uname: '墨子',
imgSrc: './images/9.5/10.jpg',
},
{
uname: '鲁班',
imgSrc: './images/9.5/11.jpg',
},
{
uname: '嬴政',
imgSrc: './images/9.5/12.jpg',
},
{
uname: '孙膑',
imgSrc: './images/9.5/13.jpg',
},
{
uname: '周瑜',
imgSrc: './images/9.5/14.jpg',
},
{
uname: '老夫子',
imgSrc: './images/9.5/15.jpg',
},
{
uname: '狄仁杰',
imgSrc: './images/9.5/16.jpg',
},
{
uname: '扁鹊',
imgSrc: './images/9.5/17.jpg',
},
{
uname: '马可波罗',
imgSrc: './images/9.5/18.jpg',
},
{
uname: '露娜',
imgSrc: './images/9.5/19.jpg',
},
{
uname: '孙悟空',
imgSrc: './images/9.5/20.jpg',
},
{
uname: '黄忠',
imgSrc: './images/9.5/21.jpg',
},
{
uname: '百里玄策',
imgSrc: './images/9.5/22.jpg',
},
];
let text = document.querySelector('textarea');
let num = document.querySelector('.useCount');
let btn = document.querySelector('#send');
let ul = document.querySelector('#list');
// 获取当前时间
function getFormatTime() {
let nowDate = new Date();
let year = nowDate.getFullYear();
let month = nowDate.getMonth();
let day = nowDate.getDate();
let hour = nowDate.getHours();
let minute = nowDate.getMinutes();
let second = nowDate.getSeconds();
month = month < 10 ? '0' + ++month : month;
day = day < 10 ? '0' + ++day : day;
hour = hour < 10 ? '0' + ++hour : hour;
minute = minute < 10 ? '0' + ++minute : minute;
second = second < 10 ? '0' + ++second : second;
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
}
text.addEventListener('input', function () {
let num1 = text.value.length;
num.innerHTML = num1;
});
btn.addEventListener('click', function () {
let random = Math.floor(Math.random() * dataArr.length);
console.log(random);
let li = document.createElement('li');
let test = text.value;
let time = getFormatTime();
li.innerHTML = `
<div class="info">
<img class="userpic" src="${dataArr[random].imgSrc}" />
<span class="username">${dataArr[random].uname}</span>
<p class="send-time">发布于 ${time}</p>
</div>
<div class="content">${test}</div>
<span class="the_del">X</span>
`;
ul.appendChild(li);
text.value = '';
num.innerHTML = 0;
let del = document.querySelector('.the_del');
del.addEventListener('click', function () {
console.log(this.parentNode);
this.parentNode.remove();
});
});
</script>
发布微博案例
需求1:检测用户输入字数
1. 注册input事件
2. 将文本的内容的长度赋值给对应的数值
3. 表单的maxlength属性可以直接限制在200个数之间
需求2: 输入不能为空
判断如果内容为空,则提示不能输入为空, 并且直接return 不能为空
防止输入无意义空格, 使用字符串.trim()去掉首尾空格
并将表单的value值设置为空字符串
同时下面红色为设置为0
需求3: 新增留言
创建一个小li,然后里面通过innerHTML追加数据
随机获取数据数组里面的内容, 替换newNode的图片和名字以及留言内容
利用时间对象将时间动态化 new Date().toLocaleString()
追加给 ul
需求4:删除留言
在事件处理函数里面获取点击按钮,注册点击事件
删除对应的元素 (通过this获取对应的那条需要删除的元素)
需求5:重置
将表单域内容重置为空
将userCount里面的内容重置为0
代码图
<div class="w">
<div class="controls">
<img src="images/tip.png" alt="" /><br />
<textarea
placeholder="说点什么吧..."
id="area"
cols="30"
rows="100"
maxlength="200"
></textarea>
<div>
<span class="useCount">0</span>
<span>/</span>
<span>200</span>
<button id="send">发布</button>
</div>
</div>
<div class="contentList">
<ul>
</ul>
</div>
</div>
<script>
let dataArr = [
{ uname: '司马懿', imgSrc: './images/9.5/01.jpg' },
{ uname: '女娲', imgSrc: './images/9.5/02.jpg' },
{ uname: '百里守约', imgSrc: './images/9.5/03.jpg' },
{ uname: '亚瑟', imgSrc: './images/9.5/04.jpg' },
{ uname: '虞姬', imgSrc: './images/9.5/05.jpg' },
{ uname: '张良', imgSrc: './images/9.5/06.jpg' },
{ uname: '安其拉', imgSrc: './images/9.5/07.jpg' },
{ uname: '李白', imgSrc: './images/9.5/08.jpg' },
{ uname: '阿珂', imgSrc: './images/9.5/09.jpg' },
{ uname: '墨子', imgSrc: './images/9.5/10.jpg' },
{ uname: '鲁班', imgSrc: './images/9.5/11.jpg' },
{ uname: '嬴政', imgSrc: './images/9.5/12.jpg' },
{ uname: '孙膑', imgSrc: './images/9.5/13.jpg' },
{ uname: '周瑜', imgSrc: './images/9.5/14.jpg' },
{ uname: '老夫子', imgSrc: './images/9.5/15.jpg' },
{ uname: '狄仁杰', imgSrc: './images/9.5/16.jpg' },
{ uname: '扁鹊', imgSrc: './images/9.5/17.jpg' },
{ uname: '马可波罗', imgSrc: './images/9.5/18.jpg' },
{ uname: '露娜', imgSrc: './images/9.5/19.jpg' },
{ uname: '孙悟空', imgSrc: './images/9.5/20.jpg' },
{ uname: '黄忠', imgSrc: './images/9.5/21.jpg' },
{ uname: '百里玄策', imgSrc: './images/9.5/22.jpg' },
];
// 文本数字
let area =document.querySelector('#area');
let useCount = document.querySelector('.useCount'); //显示数字个数
let send = document.querySelector('#send'); //发布按钮
let ul =document.querySelector('ul'); //ul
//文本域 输入事件
area.addEventListener('input',function(){
useCount.innerHTML=area.value.length;
})
//用户函数
function getUser(){
//随机数
let index = Math.round(Math.random()*(dataArr.length-2))
//调用数组
let user =dataArr[index];
return user
}
//时间函数
function getFormatTime(){
let nowDate =new Date();
let fullyear = nowDate.getFullYear();
let month = nowDate.getMonth();
let date = nowDate.getDate();
let hours = nowDate.getHours();
let minutes =nowDate.getMinutes();
let seconds =nowDate.getSeconds();
month = month < 10 ? '0' + month :month;
date = date < 10 ? '0' + date :date;
hours = hours < 10 ? '0' + hours :hours;
minutes = minutes < 10 ? '0' + minutes :minutes;
seconds = seconds < 10 ? '0' + seconds :seconds;
return `${fullyear}-${month}-${date} ${hours}-${minutes}-${seconds}`;
}
//点击发布按钮
send.addEventListener('click',function(){
//随机生成用户
let user =getUser();
let li =document.createElement('li');
let info =document.createElement('div');
info.classList.add('info');
//用户头像
let userpic =document.createElement('img');
userpic.classList.add('userpic');
userpic.src =user.imgSrc;
//用户名
let username =document.createElement('span');
username.classList.add('username');
username.innerText =user.uname;
//发布内容
let content = document.createElement('div');
// 2.1 收集用户输入的内容
// let content = area.value.trim()
// 添加用户输入内容的判断
content.classList.add('content');
content.innerText=area.value.trim();
if (content.innerText.length == 0) {
alert('请输入内容')
return
}
//发布事件
let sendTime =document.createElement('p');
sendTime.classList.add('send-time');
sendTime.innerText=getFormatTime();
// console.log(li,info,userpic,user,username,content,sendTime);
info.append(userpic,username,sendTime);
// console.log(info);
//删除按钮
let the_del = document.createElement('span');
the_del.classList.add('the_del');
the_del.innerText='X';
//删除点击事件
the_del.addEventListener('click',function(){
this.parentNode.remove();
})
//添加多个li
li.append(info,content,the_del);
// console.log(li);
//添加一个元素
ul.appendChild(li);
console.log(ul);
area.value=''
useCount.innerText='0'
})
</script>
.add(‘content’);
content.innerText=area.value.trim();
if (content.innerText.length == 0) {
alert(‘请输入内容’)
return
}
//发布事件
let sendTime =document.createElement(‘p’);
sendTime.classList.add(‘send-time’);
sendTime.innerText=getFormatTime();
// console.log(li,info,userpic,user,username,content,sendTime);
info.append(userpic,username,sendTime);
// console.log(info);
//删除按钮
let the_del = document.createElement('span');
the_del.classList.add('the_del');
the_del.innerText='X';
//删除点击事件
the_del.addEventListener('click',function(){
this.parentNode.remove();
})
//添加多个li
li.append(info,content,the_del);
// console.log(li);
//添加一个元素
ul.appendChild(li);
console.log(ul);
area.value=''
useCount.innerText='0'
})
</script>