WEB APIs ( JS DOM )
一、DOM
DOM(文本对象模型):用来呈现以及任意HTML或XML文档交互的API,实现用户交互
BOM(浏览器对象模型)
作用:就是通过JS取操作HTML和浏览器
DOM树:将HTML文档以树状结构直观的表现出来。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>点击</button>
<script>
let btn = document.querySelector('button');
console.dir(btn) //console.dir() 打印对象
btn.innerHTML = '唐伯虎';
</script>
</body>
</html>
document对象:
DOM里提供的对象
所以它提供的属性和方法都是用来访问和操作网页内容的
1.1 获取元素
根据CSS选择器来获取DOM元素(重点)
匹配单个元素
语法:document.querySelector('css选择器')
参数:包含一个或多个有效的CSS选择器 字符串
返回值:CSS选择器匹配的第一个元素,一个 HTMLElement对象。如果没有匹配到,则返回null
选择匹配的多个元素
语法:querySelectorAll('css选择器')
参数:包含一个或多个有效的CSS选择器 字符串
返回值:CSS选择器匹配的NodeList 对象集合(伪数组)
得到得一个伪数组:
- 有长度有索引号的数组
- 但是没有 pop() push() 等数组方法
想要得到里面的每一个对象,则需要遍历(for)的方式获得。
注意:只要通过querySelectorAll
获得的数值,得到的都是数组。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul class="nav">
<li>我的首页</li>
<li>产品介绍</li>
<li>联系方式</li>
</ul>
<script>
let lis = document.querySelectorAll('ul.nav li');
for (let i = 0; i < lis.length; i++) {
console.log(lis[i]);
}
</script>
</body>
</html>
其他获取DOM元素方法(了解)
//根据id获取一个元素
document.getElementById('nav');
//根据 标签获取一个元素
document.getElementsByTagName('div');
//根据 类名中包含w的类名的元素
document.getElementsByClassName('w')
1.2 修改元素内容及案例
document.write() 方法
只能将文本内容追加到
</body>
前面的位置文本中包含的标签会被解析
对象.innerText 属性
将文本内容添加/更新到任意标签位置
文本中包含的标签不会被解析。不识别标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
width: 200px;
height: 200px;
background-color: #66ccff;
}
</style>
</head>
<body>
<div>
蓝色的记忆
</div>
<script>
let box = document.querySelector('div');
box.innerText = '66ccff';
</script>
</body>
</html>
对象.innerHTML 属性
- 将文本内容添加/更新到任意标签位置
- 文本中包含的标签会被解析
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
width: 200px;
height: 200px;
background-color: #66ccff;
}
</style>
</head>
<body>
<div>
蓝色的记忆
</div>
<script>
let box = document.querySelector('div');
box.innerText = '66ccff';
box.innerHTML = '<strong>66ccff</strong><br>我是张三';
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div {
display: inline-block;
width: 150px;
height: 30px;
border: 1px solid pink;
vertical-align: middle;
text-align: center;
line-height: 30px;
/* margin: 300px; */
}
</style>
</head>
<body>
抽取选手:<div></div>
<script>
let box = document.querySelector('div');
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
let arr = ['nahida','barbatos','Morax','Beelzebul'];
let random = getRandom(0, arr.length - 1);
box.innerHTML = arr[random];
arr.splice(random,1);
</script>
</body>
</html>
1.3 修改元素属性及案例
设置/修改元素常用属性
语法:
对象.属性 = 值
- 还可以通过 JS 设置/修改标签元素属性,比如通过 src更换 图片
- 最常见的属性比如: href、title、src 等
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="./images/1.webp">
<script>
//1. 获取元素
let pic = document.querySelector('img');
pic.src = "./images/2.webp";
pic.title = '刘德华';
</script>
</body>
</html>刷新页面,图片随机更新
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
img{
width: 500px;
height: 300px;
}
</style>
</head>
<body>
<img src="./images/1.webp" alt="">
<script>
// 获取元素
let pic = document.querySelector('img');
//随机
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
let random = getRandom(1,6);
pic.src = `./images/${random}.webp`
</script>
</body>
</html>
设置/修改元素样式属性
还可以通过 JS 设置/修改标签元素的样式属性。
- 比如通过 轮播图小圆点自动更换颜色样式
- 点击按钮可以滚动图片,这是移动的图片的位置 left 等等
路径:
- 通过 style 属性操作CSS
- 操作类名(className) 操作CSS
- 通过 classList 操作类控制CSS
语法:
对象.style.样式属性 = 值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
width: 500px;
height: 300px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<script>
let box = document.querySelector('div');
box.style.width = '700px';
box.style.height = '200px';
box.style.backgroundColor = '#66ccff';
</script>
</body>
</html>注意:
\1. 修改样式通过style属性引出
\2. 如果属性有-连接符,需要转换为小驼峰命名法
\3. 赋值的时候,需要的时候不要忘记加css单位
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body{
background-image: url("./images/desktop_1.jpg");
}
</style>
</head>
<body>
<div></div>
<script>
let box = document.querySelector('body');
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
let random = getRandom(1,10);
box.style.backgroundImage = `url("./images/desktop_${random}.jpg")`;
</script>
</body>
</html>
1.4 修改元素样式 - className和classList
1.4.1 操作类名(className) 操作CSS
如果修改的样式比较多,直接通过style属性修改比较繁琐,我们可以通过借助于css类名的形式。
语法 : 元素.className = 新值;
注意:
\1. 由于class是关键字, 所以使用className去代替
\2. className是使用新值换旧值, 如果需要添加一个类,需要保留之前的类名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
}
.active{
width: 300px;
height: 300px;
background-color: #66ccff;
}
</style>
</head>
<body>
<div class="one"></div>
<script>
let box = document.querySelector('div');
box.className = 'active' //换一个类名
box.className = 'one active' //保留旧的类名one ,新增加一个类名active
</script>
</body>
</html>
1.4.2 通过 classList 操作类控制CSS
为了解决className 容易覆盖以前的类名,我们可以通过classList方式追加和删除类名。
语法:
元素.classList.add('类名'); //追加一个类
元素.classList.remove('类名'); //删除一个类
元素.classList.toggle('类名'); //切换一个类。如果有类就切换成另外一个类;没有这个类就新增加一个类
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
}
.active{
width: 300px;
height: 300px;
background-color: #66ccff;
}
.
</style>
</head>
<body>
<div class="one"></div>
<script>
let box = document.querySelector('div');
box.className = 'active' //换一个类名
box.className = 'one active' //保留旧的类名one ,新增加一个类名active
box.classList.add('active');
box.classList.remove('one');
box.classList.toggle('one'); ////切换一个类。如果有one类就切换成one个类;没有one类就新增加one类
</script>
</body>
</html>
1.5 修改表单属性
表单很多情况,也需要修改属性,比如点击眼睛,可以看到密码,本质是把表单类型转换为文本框
正常的有属性有取值的 跟其他的标签属性没有任何区别
获取:DOM对象.属性值
设置:DOM对象.属性值 = 新值
表单属性中添加就有效果,移除就没有效果,一律使用布尔值表示 如果为true 代表添加了该属性 如果是false 代表移除了该属性。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" value="请输入">
<button disabled>按钮</button>
<input type="checkbox" checked class="agree">
<script>
let input = document.querySelector('input');
input.value = '小米手机';
input.type = 'password';
let btn = document.querySelector('button');
btn.disabled = true; //true 是按钮禁用,false是可用
let checkbox = document.querySelector('input.agree');
checkbox.checked = false; //true 是已选,false是未选
</script>
</body>
</html>
1.6 定时器间歇函数
能够说出定时器函数在开发中的使用场景。每隔一段时间需要自动执行一段代码,不需要我们手动去触发。
定时器的基本使用
开启定时器,间隔时间是毫秒:
setInterval(函数,间隔时间)
注意:
- 函数名字不需要加括号
- 定时器返回的是一个id数字
setInterval(function () {
console.log('暴富');
},1000)
function show(){
console.log('月薪过万');
}
- 关闭定时器
let 变量名 = setInterval(函数,间隔时间);
clearInterval(变量名)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
function fn () {
console.log('暴富');
}
setInterval(fn,1000); //启动定时器
let time = setInterval(fn,1000)
clearInterval(time); //关闭定时器
</script>
</body>
</html>
案例倒计时效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<textarea name="" id="" cols="30" rows="10">
用户注册协议
欢迎注册成为京东用户!在您注册过程中,您需要完成我们的注册流程并通过点击同意的形式在线签署以下协议,请您务必仔细阅读、充分理解协议中的条款内容后再点击同意(尤其是以粗体或下划线标识的条款,因为这些条款可能会明确您应履行的义务或对您的权利有所限制)。
【请您注意】如果您不同意以下协议全部或任何条款约定,请您停止注册。您停止注册后将仅可以浏览我们的商品信息但无法享受我们的产品或服务。如您按照注册流程提示填写信息,阅读并点击同意上述协议且完成全部注册流程后,即表示您已充分阅读、理解并接受协议的全部内容,并表明您同意我们可以依据协议内容来处理您的个人信息,并同意我们将您的订单信息共享给为完成此订单所必须的第三方合作方(详情查看
</textarea>
<br>
<button class="btn" disabled>我已经阅读用户协议(6)</button>
<script>
let btn = document.querySelector('button');
let num = 6;
let time = setInterval(function () {
num--;
btn.innerHTML = ``;
if (num === 0){
clearInterval(time);
btn.innerHTML = ``;
setAble();
}
},1000)
function setAble (){
btn.disabled = false;
}
</script>
</body>
</html>
1.7 综合案例-焦点图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>QQ音乐10屏轮播图</title>
<style>
.img-box {
width: 700px;
height: 320px;
margin: 50px auto 0;
background: #000;
position: relative;
}
.img-box .tip {
width: 700px;
height: 53px;
line-height: 53px;
position: absolute;
bottom: 0px;
background-color: rgba(0, 0, 0, 0.8);
z-index: 10;
}
.img-box .tip h3 {
width: 82%;
margin: 0;
margin-right: 20px;
padding-left: 20px;
color: #98E404;
font-size: 28px;
float: left;
font-weight: 500;
font-family: "Microsoft Yahei", Tahoma, Geneva;
}
.img-box .tip a {
width: 30px;
height: 29px;
display: block;
float: left;
margin-top: 12px;
margin-right: 3px;
}
.img-box ul {
position: absolute;
bottom: 0;
right: 30px;
list-style: none;
z-index: 99;
}
</style>
</head>
<body>
<div class="img-box">
<img class="pic" src="images/b01.jpg" alt="第1张图的描述信息">
<div class="tip">
<h3 class="text">挑战云歌单,欢迎你来</h3>
</div>
</div>
<script>
//数据
let data = [
{
imgSrc: 'images/b01.jpg',
title: '挑战云歌单,欢迎你来'
},
{
imgSrc: 'images/b02.jpg',
title: '田园日记,上演上京记'
},
{
imgSrc: 'images/b03.jpg',
title: '甜蜜攻势再次回归'
},
{
imgSrc: 'images/b04.jpg',
title: '我为歌狂,生为歌王'
},
{
imgSrc: 'images/b05.jpg',
title: '年度校园主题活动'
},
{
imgSrc: 'images/b06.jpg',
title: 'pink老师新歌发布,5月10号正式推出'
},
{
imgSrc: 'images/b07.jpg',
title: '动力火车来到西安'
},
{
imgSrc: 'images/b08.jpg',
title: '钢铁侠3,英雄镇东风'
},
{
imgSrc: 'images/b09.jpg',
title: '我用整颗心来等你'
},
];
//获取元素
let pic = document.querySelector('img.pic');
let text = document.querySelector('h3.text');
let i = 0;
//启动定时器
let time = setInterval(function () {
i++;
pic.src = data[i].imgSrc;
text.innerHTML = data[i].title;
if (i === data.length-1) {
i = -1;
}
},1000)
</script>
</body>
</html>
二、事件监听及案例
2.1 事件
事件是在编程时系统内发生的动作或者发生的事情,比如用户在网页上单击一个按钮
2.2 事件监听(绑定事件)
就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为 注册事件
给元素添加事件,语法: 元素.addEventListener('事件',要执行的函数);
2.3 事件监听三要素:
事件源: 那个dom元素被事件触发了,要获取dom元素
事件: 用什么方式触发,比如鼠标单击 click、鼠标经过 mouseover 等
事件调用的函数: 要做什么事
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>点击</button>
<script>
let btn = document.querySelector('button');
// btn.addEventListener('click',function (){
// alert('被点击了');
// })
function fn() {
alert('考研上岸')
}
btn.addEventListener('click',fn);
</script>
</body>
</html>
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.erweima {
position: relative;
width: 160px;
height: 160px;
margin: 100px auto;
border: 1px solid #ccc;
}
.erweima i {
position: absolute;
left: -13px;
top: 0;
width: 10px;
height: 10px;
border: 1px solid #ccc;
font-size: 12px;
line-height: 10px;
color: #ccc;
font-style: normal;
cursor: pointer;
}
</style>
</head>
<body>
<div class="erweima">
<img src="./images/code.png" alt="">
<i class="close_btn">x</i>
</div>
<script>
// 1. 获取元素 事件源 i 关闭的 erweima
let close_btn = document.querySelector('i.close_btn');
let erweima = document.querySelector('div.erweima');
// 2. 事件监听
close_btn.addEventListener('click',function () {
// erweima 关闭 他是隐藏的
erweima.style.display = 'none';
})
</script>
</body>
</html>
2.4 案例-随机点名
点名1
<!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>Document</title>
<style>
div {
width: 200px;
height: 40px;
border: 1px solid pink;
text-align: center;
line-height: 40px;
}
</style>
</head>
<body>
<div>开始抽奖吧</div>
<button>点击点名</button>
<script>
// 1. 获取元素 div 和 button
let btn = document.querySelector('button');
let Name = document.querySelector('div')
// 2. 随机函数
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min ;
}
// 声明一个数组
let arr = ['刘备', '曹操', '张三'];
// 3. 事件监听
let i = 0;
btn.addEventListener('click',function () {
i = getRandom(0,arr.length-1)
Name.innerHTML = arr[i];
arr.splice(i,1);
if (arr.length === 0){
btn.disabled = true;
}
})
</script>
</body>
</html>
点名2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
h2 {
text-align: center;
}
.box {
width: 600px;
margin: 50px auto;
display: flex;
font-size: 25px;
line-height: 40px;
}
.qs {
width: 450px;
height: 40px;
color: red;
}
.btns {
text-align: center;
}
.btns button {
width: 120px;
height: 35px;
margin: 0 50px;
}
</style>
</head>
<body>
<h2>随机点名</h2>
<div class="box">
<span>名字是:</span>
<div class="qs">这里显示姓名</div>
</div>
<div class="btns">
<button class="start">开始</button>
<button class="end">结束</button>
</div>
<script>
// 数据数组
let arr = ['马超', '黄忠', '赵云', '关羽', '张飞']
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
// 1. 获取元素 两个按钮 + div
// 一定不要忘记加点 因为里面写css类选择器
let name = document.querySelector('div.qs');
let startBtn = document.querySelector('button.start');
let endBtn = document.querySelector('button.end');
// timer 要是全局变量
let timer = 0;
// random 要是全局变量
let random = 0;
// 2. 给开始按钮注册事件
console.log(arr);
startBtn.addEventListener('click',function (){
timer = setInterval(function (){
random = getRandom(0,arr.length-1);
name.innerHTML = arr[random];
},25)
if (arr.length ===1){
startBtn.disabled = endBtn.disabled = true;
}
})
// 3. 给结束按钮注册事件 本质是停止定时器
endBtn.addEventListener('click', function () {
// 停止定时器
clearInterval(timer);
// 删除数组元素
arr.splice(random,1);
console.log(arr);
})
</script>
</body>
</html>
2.5 事件扩展
事件监听版本
事件源.on事件 = function(){}
btn.onclick = function(){}
btn.onclick = fn
function fn(){}事件源.addEventList(事件,事件处理函数);
(建议用这种)
事件类型:
鼠标事件
- click 鼠标点击
- mouseenter 鼠标经过
- mouseleave 鼠标离开
焦点事件(表单获得光标)
- focus 获得焦点
- blur 失去焦点
键盘事件
- Keydown 键盘按下触发
- Keyup 键盘抬起触发
文本事件(表单输入触发)
- input 用户输入事件
2.6 案例-小米搜索框
<!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>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
.mi {
position: relative;
width: 223px;
margin: 100px auto;
}
.mi input {
width: 223px;
height: 48px;
padding: 0 10px;
font-size: 14px;
line-height: 48px;
border: 1px solid #e0e0e0;
outline: none;
transition: all .3s;
}
.mi .search {
border: 1px solid #ff6700;
}
.result-list {
display: none;
position: absolute;
left: 0;
top: 48px;
width: 223px;
border: 1px solid #ff6700;
border-top: 0;
background: #fff;
}
.result-list a {
display: block;
padding: 6px 15px;
font-size: 12px;
color: #424242;
text-decoration: none;
}
.result-list a:hover {
background-color: #eee;
}
</style>
</head>
<body>
<div class="mi">
<input type="search" placeholder="小米笔记本">
<ul class="result-list">
<li><a href="#">全部商品</a></li>
<li><a href="#">小米12</a></li>
<li><a href="#">小米12SU</a></li>
<li><a href="#">小米笔记本</a></li>
<li><a href="#">小米手机</a></li>
<li><a href="#">黑鲨4</a></li>
<li><a href="#">空调</a></li>
</ul>
</div>
<script>
let search = document.querySelector('input');
let result = document.querySelector('ul.result-list');
//事件监听
search.addEventListener('focus',function () {
//显示下拉菜单
result.style.display = 'block' ;
//文本框变色
search.classList.add('search');
})
search.addEventListener('blur',function (){
//隐藏下拉菜单
result.style.display = 'none';
//文本框变色
search.classList.remove('search');
})
</script>
</body>
</html>
2.7 微博输入案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="css/weibo.css">
</head>
<body>
<div class="w">
<div class="controls">
<img src="images/tip.png" alt=""><br>
<textarea placeholder="说点什么吧..." id="area" cols="30" rows="10" 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 area = document.querySelector('#area');
let useCount = document.querySelector('span.useCount');
let num = 0;
//绑定事件
area.addEventListener('input',function () {
//不断获得文本域的字符长度
num = area.value.length;
useCount.innerHTML = num;
})
if (num === 200){
area.disabled = true;
}
</script>
</body>
</html>
2.8 案例-全选
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #c0c0c0;
width: 500px;
margin: 100px auto;
text-align: center;
}
th {
background-color: #09c;
font: bold 16px "微软雅黑";
color: #fff;
height: 24px;
}
td {
border: 1px solid #d0d0d0;
color: #404060;
padding: 10px;
}
.allCheck {
width: 80px;
}
</style>
</head>
<body>
<table>
<tr>
<th class="allCheck">
<input type="checkbox" name="" id="checkAll"> <span class="all">全选</span>
</th>
<th>商品</th>
<th>商家</th>
<th>价格</th>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米手机</td>
<td>小米</td>
<td>¥1999</td>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米净水器</td>
<td>小米</td>
<td>¥4999</td>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米电视</td>
<td>小米</td>
<td>¥5999</td>
</tr>
</table>
<script>
// 1. 获取元素 全选 和 ck 小复选框
let all = document.querySelector('#checkAll');
let cks = document.querySelectorAll('.ck');
let span = document.querySelector('span');
// 2. 事件监听 全选按钮
all.addEventListener('click',function () {
for (let i = 0; i < cks.length; i++) {
cks[i].checked = all.checked;
}
if (all.checked){
span.innerHTML = '取消';
}else{
span.innerHTML = '全选';
}
})
// 3. 小按钮的做法 同时给多个元素绑定相同事件
//遍历下面所有的checkbox,绑定点击事件
//在事件内部,遍历所有checkbox状态。只要有一个为false,就将全状态为false,文字改为全选,并直接退出(退出循环)
//在循环结束将全选状态直接设置为true
for (let i = 0; i < cks.length; i++) {
cks[i].addEventListener('click',function () {
for (let j = 0; j < cks.length; j++) { //只要点击一个小按钮,就要遍历所有的小按钮的选中状态
if (!cks[i].checked){ //如果当中有个小按钮选中状态为false
all.checked = false;
span.innerHTML = '全选';
return; //退出这个函数,不再进行接下来的操作
}
}
all.checked = true; //当遍历完小按钮,代码走到这里,就说明说所有的按钮都被选中了
span.innerHTML = '取消';
})
}
</script>
</body>
</html>
// break 退出当前循环
// continue 退出当前循环
// return 退出当前函数
2.8.1 购物车加减案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div {
width: 80px;
}
input[type=text] {
width: 50px;
height: 44px;
outline: none;
border: 1px solid #ccc;
text-align: center;
border-right: 0;
}
input[type=button] {
height: 24px;
width: 22px;
cursor: pointer;
}
input {
float: left;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<div>
<input type="text" id="total" value="0" readonly>
<input type="button" value="+" id="add">
<input type="button" value="-" id="reduce" disabled>
<script>
//获取3个元素
let total = document.querySelector('#total');
let add = document.querySelector('#add');
let reduce = document.querySelector('#reduce');
add.addEventListener('click',function () {
// total.value = +total.value + 1
total.value++;
reduce.disabled = false;
})
reduce.addEventListener('click',function () {
// total.value = +total.value + 1
total.value--;
if (total.value <= 0){ //隐式转换
reduce.disabled = true;
}
})
</script>
</div>
</body>
</html>
2.8.2 高阶函数-回调函数
高阶函数可以被简单理解为函数的高级应用,JavaScript 中函数可以被当成【值】来对待,基于这个特性实现函数的高级应用。
回调函数把函数当做另外一个函数的参数传递,这个函数就叫回调函数 ,回调函数本质还是函数,只不过把它当成参数使用,使用匿名函数做为回调函数比较常见
如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数。简单理解: 当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数 。
三、环境对象
环境对象指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境
作用:弄清楚this的指向,可以让我们代码更简洁
<!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>Document</title>
</head>
<body>
<button>点击</button>
<script>
// 环境对象 this 他就是个对象
function fn() {
console.log(this) //直接调用函数,其实相当于是 window.函数,所以 this 指代 window
}
// fn() window是省略的
window.fn()
let btn = document.querySelector('button')
btn.addEventListener('click', function () {
console.log(typeof this)
// 因为btn 调用了这个函数,所以 this 指向btn
})
</script>
</body>
</html>
3.1环境对象 this
【谁调用, this 就是谁】 是判断 this 指向的粗略规则
3.2 排他思想
当前元素为A状态,其他元素为B状态
干掉所有人
使用for循环
复活他自己
通过this或者下标找到自己或者对应的元素
<!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>Document</title>
<style>
.pink {
background: pink;
}
</style>
</head>
<body>
<button class="pink">第1个</button><button>第2个</button><button>第3个</button><button>第4个</button><button>第5个</button>
<script>
let btns = document.querySelectorAll('button')
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function () {
// this.classList.add('pink')
// 干掉所有人
// for (let j = 0; j < btns.length; j++) {
// btns[j].classList.remove('pink')
// }
document.querySelector('.pink').classList.remove('pink'); //找到第一个是class是pink的,然后移除
// 复活我自己,然后复活自己的,使得自己的class是pink。可以用在首页,tab页上
this.classList.add('pink')
})
}
</script>
</body>
</html>
3.3 综合案例 tab栏
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" />
<title></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
.wrapper {
width: 1000px;
height: 475px;
margin: 0 auto;
margin-top: 100px;
}
.tab {
border: 1px solid #ddd;
border-bottom: 0;
height: 36px;
width: 320px;
}
.tab li {
position: relative;
float: left;
width: 80px;
height: 34px;
line-height: 34px;
text-align: center;
cursor: pointer;
border-top: 4px solid #fff;
}
.tab span {
position: absolute;
right: 0;
top: 10px;
background: #ddd;
width: 1px;
height: 14px;
overflow: hidden;
}
.products {
width: 1002px;
border: 1px solid #ddd;
height: 476px;
}
.products .main {
float: left;
display: none;
}
.products .main.active {
display: block;
}
.tab li.active {
border-color: red;
border-bottom: 0;
}
</style>
</head>
<body>
<div class="wrapper">
<ul class="tab">
<li class="tab-item active">国际大牌<span>◆</span></li>
<li class="tab-item">国妆名牌<span>◆</span></li>
<li class="tab-item">清洁用品<span>◆</span></li>
<li class="tab-item">男士精品</li>
</ul>
<div class="products">
<div class="main active">
<a href="###"><img src="imgs/guojidapai.jpg" alt="" /></a>
</div>
<div class="main">
<a href="###"><img src="imgs/guozhuangmingpin.jpg" alt="" /></a>
</div>
<div class="main">
<a href="###"><img src="imgs/qingjieyongpin.jpg" alt="" /></a>
</div>
<div class="main">
<a href="###"><img src="imgs/nanshijingpin.jpg" alt="" /></a>
</div>
</div>
</div>
<script>
let lis = document.querySelectorAll('li.tab-item');
let goods = document.querySelectorAll('.products .main')
//头部tab栏目切换
for (let i = 0; i < lis.length; i++) {
lis[i].addEventListener('click',function () {
document.querySelector('.tab .active').classList.remove('active');
this.classList.add('active')
//底下的商品变化
document.querySelector('.products .active').classList.remove('active')
//对应的i值的main那个显示内容
goods[i].classList.add('active')
})
}
</script>
</body>
</html>
四、DOM节点
DOM树里每一个内容都称之为节点
元素节点 •
- 所有的标签: 比如 body、 div ,html 是根节点
- 属性节点 :所有的属性 比如 href
- 文本节点 : 所有的文本
- 其他
4.1 查找结点及二维码案例
4.2 查找父节点(重点)
parentNode 属性 子元素.parentNode;
返回最近一级的父节点 找不到返回为null
<!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>Document</title>
</head>
<body>
<div class="father">
<div class="son">儿子</div>
</div>
<script>
let son = document.querySelector('.son')
// 找爸爸
console.log(son.parentNode)
son.parentNode.style.display = 'none'
</script>
</body>
</html>
关闭二维码加强版:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.erweima {
position: relative;
width: 160px;
height: 160px;
margin: 100px auto;
border: 1px solid #ccc;
}
.erweima i {
position: absolute;
left: -13px;
top: 0;
width: 10px;
height: 10px;
border: 1px solid #ccc;
font-size: 12px;
line-height: 10px;
color: #ccc;
font-style: normal;
cursor: pointer;
}
</style>
</head>
<body>
<div class="erweima">
<img src="./images/code.png" alt="">
<i class="close_btn">x</i>
</div>
<script>
// 1. 获取元素 事件源 i 关闭的 erweima
let close_btn = document.querySelector('.close_btn')
// 2. 事件监听
close_btn.addEventListener('click', function () {
// 找到close_btn的父节点,并隐藏这个元素
this.parentNode.style.display = 'none'
})
</script>
</body>
</html>
关闭4个二维码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.erweima {
width: 149px;
height: 152px;
border: 1px solid #000;
background: url(./images/456.png) no-repeat;
position: relative;
}
.close {
position: absolute;
right: -52px;
top: -1px;
width: 50px;
height: 50px;
background: url(./images/bgs.png) no-repeat -159px -102px;
cursor: pointer;
border: 1px solid #000;
}
</style>
</head>
<body>
<div class="erweima">
<span class="close"></span>
</div>
<div class="erweima">
<span class="close">1</span>
</div>
<div class="erweima">
<span class="close">2</span>
</div>
<div class="erweima">
<span class="close">3</span>
</div>
<div class="erweima">
<span class="close">4</span>
</div>
<script>
// 1. 获取元素 关闭按钮
let close_btn = document.querySelectorAll('.close');
for (let i = 0; i < close_btn.length; i++) {
close_btn[i].addEventListener('click',function () {
//this.parentNode.style.display = 'none';
this.parentNode.style.visibility = 'hidden';
})
}
</script>
</body>
</html>
4.3 查找结点-子级和兄弟
子节点查找(重点):父元素.children
- 仅获得所有元素节点
- 返回的还是一个伪数组
下一个兄弟节点:元素.nextElementSibling
上一个兄弟节点: 元素.previousElementSibling
4.4 追加结点
一般情况下,我们新增节点,按照如下操作:
创建一个新的节点 let 新元素 = document.createElement('标签名')
把创建的新的节点放入到指定的元素内部
父元素.appendChild(新元素)
插入到父元素的最后一个子元素:
父元素.insertBefore(新元素, 在哪个元素前面)
插入到父元素中某个子元素的前面
4.5 综合案例-学成在线
需求:按照数据渲染页面 分析:
①:准备好空的ul 结构
②:根据数据的个数,创建一个新的空li
③:li里面添加内容 img 标题等
④:追加给ul
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>学车在线首页</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- 4. box核心内容区域开始 -->
<div class="box w">
<div class="box-hd">
<h3>精品推荐</h3>
<a href="#">查看全部</a>
</div>
<div class="box-bd">
<ul class="clearfix">
<!-- <li>-->
<!-- <img src="./images/course01.png" alt="">-->
<!-- <h4>-->
<!-- Think PHP 5.0 博客系统实战项目演练-->
<!-- </h4>-->
<!-- <div class="info">-->
<!-- <span>高级</span> • <span> 1125</span>人在学习-->
<!-- </div>-->
<!-- </li> -->
</ul>
</div>
</div>
<script>
let data = [
{
src: 'images/course01.png',
title: 'Think PHP 5.0 博客系统实战项目演练',
num: 1125
},
{
src: 'images/course02.png',
title: 'Android 网络动态图片加载实战',
num: 357
},
{
src: 'images/course03.png',
title: 'Angular2 大前端商城实战项目演练',
num: 22250
},
{
src: 'images/course04.png',
title: 'Android APP 实战项目演练',
num: 389
},
{
src: 'images/course05.png',
title: 'UGUI 源码深度分析案例',
num: 124
},
{
src: 'images/course06.png',
title: 'Kami2首页界面切换效果实战演练',
num: 432
},
{
src: 'images/course07.png',
title: 'UNITY 从入门到精通实战案例',
num: 888
},
{
src: 'images/course08.png',
title: '我会变,你呢?',
num: 590
},
{
src: 'images/course08.png',
title: '我会变,你呢?',
num: 590
}
];
let ui = document.querySelector('ul ')
//根据数据的个数创建li的个数
for (let i = 0; i < data.length; i++) {
//创建li
let li = document.createElement('li');
//准备好内容
li.innerHTML = `
`
//再追加给ul
ui.appendChild(li);
}
</script>
</body>
</html>
4.6 克隆和删除结点
4.6.1 克隆节点
元素.cloneNode(布尔值)
克隆一个已有的元素结点
特殊情况下,我们新增节点,按照如下操作:
- 复制一个原有的节点
- 把复制的节点放入到指定的元素内部
cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值
若为true,则代表克隆时会包含后代节点一起克隆 (连孩子一块打包克隆)
若为false,则代表克隆时不包含后代节点 (只克隆当前结点,不克隆后代结点)
默认为false
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
<li>我是内容</li>
</ul>
<script>
let ul = document.querySelector('ul');
let newul = ul.cloneNode(true);
document.body.appendChild(newul);
</script>
</body>
</html>
4.6.2 删除结点
若一个节点在页面中已不需要时,可以删除它
在 JavaScript 原生DOM操作中,要删除元素必须通过父元素删除
语法:父元素.removeChild(要删除的元素);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>点击</button>
<ul>
<li>我是内容</li>
</ul>
<script>
let ul = document.querySelector('ul');
let btn = document.querySelector('button')
btn.addEventListener('click',function () {
//删除的结点
ul.removeChild(ul.children[0]);
})
</script>
</body>
</html>
五、时间对象
5.1 时间对象及案例
实例化
获得当前时间: let date = new Date();
获得指定时间:let date = new Date('1970-01-01 22:30:23');
获得时间对象的方法:
[]
<!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>Document</title>
<style>
div {
width: 400px;
height: 50px;
background-color: pink;
text-align: center;
line-height: 50px;
}
</style>
</head>
<body>
<div></div>
<script>
let arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
let div = document.querySelector('div')
// 先调用,就省去了1秒的空白期
getTime()
setInterval(getTime, 1000)
function getTime() {
// 1. 实例化时间对象 一定写到定时器里面才可以
let date = new Date() //获得当前时间
let year = date.getFullYear()
let month = date.getMonth() + 1 //获得月份 因为是数组下标值0-11,得在后面加1
let date1 = date.getDate() //今天是一个月的几号?
let hour = date.getHours()
let min = date.getMinutes()
let sec = date.getSeconds()
let day = date.getDay() //获取星期
div.innerHTML = ``
}
</script>
</body>
</html>
5.2 时间戳及案例
时间戳:是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式
获取时间戳的三种方法:
- 使用 getTime() 方法
let date = new Data();
console.log(date.getTime);
- 简写 +new Date()
console.log(+new Date());
console.log(+new Date('2022-8-30 12:00:00')) // 指定时间的时间戳
- 使用Date().now:无需实例化,但是只能得到当前的时间戳, 而前面两种可以返回指定时间的时间戳
console.log(Date.now());
<!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>Document</title>
<style>
.countdown {
width: 240px;
height: 305px;
text-align: center;
line-height: 1;
color: #fff;
background-color: brown;
/* background-size: 240px; */
/* float: left; */
overflow: hidden;
}
.countdown .next {
font-size: 16px;
margin: 25px 0 14px;
}
.countdown .title {
font-size: 33px;
}
.countdown .tips {
margin-top: 80px;
font-size: 23px;
}
.countdown small {
font-size: 17px;
}
.countdown .clock {
width: 142px;
margin: 18px auto 0;
overflow: hidden;
}
.countdown .clock span,
.countdown .clock i {
display: block;
text-align: center;
line-height: 34px;
font-size: 23px;
float: left;
}
.countdown .clock span {
width: 34px;
height: 34px;
border-radius: 2px;
background-color: #303430;
}
.countdown .clock i {
width: 20px;
font-style: normal;
}
</style>
</head>
<body>
<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">25</span>
<i>:</i>
<span id="scond">20</span>
</p>
<p class="tips">
现在是18:30:00
</p>
</div>
<script>
let divNext = document.querySelector('.countdown .next');
let divTips = document.querySelector('.countdown .tips');
let hours = document.querySelector('#hour');
let minutes = document.querySelector('#minutes');
let secs = document.querySelector('#scond');
let endTime = +new Date('2022-8-31 18:00-00');
let timeClock = 0;
let h = 0 ;
let m = 0 ;
let ss = 0;
getTimeSS();
function getTimeSS() {
let date = new Date()
let year = date.getFullYear();
let month = date.getMonth() + 1 ; //获得月份 因为是数组下标值0-11,得在后面加1
let date1 = date.getDate(); //今天是一个月的几号?
let hour = date.getHours();
hour = hour < 10 ? '0' + hour :hour;
let min = date.getMinutes();
min = min < 10 ? '0' + min :min;
let sec = date.getSeconds();
sec = sec < 10 ? '0' + sec :sec;
let day = date.getDay();
divNext.innerHTML = `` ;
divTips.innerHTML = ``
let nowTime = +new Date();
timeClock = (endTime - nowTime) / 1000;
h =parseInt(timeClock /60 /60 %24);
h = h <10 ? '0'+h : h ;
m = parseInt(timeClock /60 %60);
m = m < 10 ? '0' + m : m ;
ss =parseInt(timeClock %60);
ss = ss <10 ? '0' +ss : ss;
hours.innerHTML = h;
minutes.innerHTML = m;
secs.innerHTML = ss;
}
setInterval(getTimeSS,1000);
</script>
</body>
</html>
5.3 案例-微博发布
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>微博发布</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
.w {
width: 900px;
margin: 0 auto;
}
.controls textarea {
width: 878px;
height: 100px;
resize: none;
border-radius: 10px;
outline: none;
padding-left: 20px;
padding-top: 10px;
font-size: 18px;
}
.controls {
overflow: hidden;
}
.controls div {
float: right;
}
.controls div span {
color: #666;
}
.controls div .useCount {
color: red;
}
.controls div button {
width: 100px;
outline: none;
border: none;
background: rgb(0, 132, 255);
height: 30px;
cursor: pointer;
color: #fff;
font: bold 14px '宋体';
transition: all 0.5s;
}
.controls div button:hover {
background: rgb(0, 225, 255);
}
.controls div button:disabled {
background: rgba(0, 225, 255, 0.5);
}
.contentList {
margin-top: 50px;
}
.contentList li {
padding: 20px 0;
border-bottom: 1px dashed #ccc;
position: relative;
}
.contentList li .info {
position: relative;
}
.contentList li .info span {
position: absolute;
top: 15px;
left: 100px;
font: bold 16px '宋体';
}
.contentList li .info p {
position: absolute;
top: 40px;
left: 100px;
color: #aaa;
font-size: 12px;
}
.contentList img {
width: 80px;
border-radius: 50%;
}
.contentList li .content {
padding-left: 100px;
color: #666;
word-break: break-all;
}
.contentList li .the_del {
position: absolute;
right: 0;
top: 0;
font-size: 28px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="w">
<!-- 操作的界面 -->
<div class="controls">
<img src="./images/9.6/tip.png" alt="" /><br />
<!-- maxlength 可以用来限制表单输入的内容长度 -->
<textarea placeholder="说点什么吧..." id="area" cols="30" rows="10" maxlength="200"></textarea>
<div>
<span class="useCount" id="useCount">0</span>
<span>/</span>
<span>200</span>
<button id="send">发布</button>
</div>
</div>
<!-- 微博内容列表 -->
<div class="contentList">
<ul id="list"></ul>
</div>
</div>
<!-- 添加了hidden属性元素会直接隐藏掉 -->
<li hidden>
<div class="info">
<img class="userpic" src="./images/9.6/03.jpg" />
<span class="username">死数据:百里守约</span>
<p class="send-time">死数据:发布于 2020年12月05日 00:07:54</p>
</div>
<div class="content">死数据:111</div>
<span class="the_del">X</span>
</li>
<script>
// maxlength 是一个表单属性, 作用是给表单设置一个最大长度
// 模拟数据
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'