思想转变及认知
在开始的时候我们学JS讲到变量声明:
可不可以把下面的let改为const?
可以,因为值没有变捏
那这个能改吗?
不可以,因为变量重新赋值了
而这个可以更改吗?
包可以的
const声明的值不能更改,而且const声明变量的时候需要在里面进行初始化
但对于引用类型,const声明的变量,里面存的不是值,是地址
地址没变,改就改了
左边的不可以改,因为地址不一样
右边的就可以了
声明变量优先使用const,发现后面要改动再改成let
为什么const声明的对象可以修改里面的属性?
因为对象是引用类型,里面存储的是地址,只要地址不变,就不会报错(数组和对象使用const声明)
什么时候使用let声明变量
如果基本数据类型的值或者引用类型的地址发生变化的时候,要用let
WebAPI的基本认知
作用和分类
作用就是用JS操作html和浏览器
分类:DOM(文档对象模型)和BOM(浏览器对象模型)
什么是DOM
DOM即Document Object Model,是文档对象模型,用来呈现以及与任意HTML或XML文档交互的API
DOM是浏览器提供的一套专门用来操作网页内容的功能
可以实现开发网页内容特效和实现用户交互
DOM树
什么是DOM树?
是将HTML文档以树状结构直观的表达出来(文档、DOM树)
描述网页内容关系的名词
作用是直观体现了标签和标签之间的关系
DOM对象
DOM对象是浏览器根据html标签生成的JS对象
所有的标签属性都可以在这个对象上面找到
而修改这个对象的属性会自动映射到标签身上
DOM的核心思想就是把网页内容当对象处理
document对象是DOM里提供的一个对象,所以它提供的属性和方法都是用来访问和操作网页内容的
网页所有内容都在document里面
总结:
获取DOM对象
我们的目标:能查找/获取DOM对象
我们想要操作某个标签首先要选中(和CSS类似)
查找元素DOM就是利用JS选择页面中的标签元素
根据CSS选择器来获取DOM元素
选择匹配的第一个元素语法是:
document.querySelector('css选择器')
参数是包含一个或多个有效的CSS选择器(字符串)
返回值是CSS选择器匹配的第一个元素,一个HTMLElement对象
<script>
const box = document.querySelector('div')
console.log(box)
</script>
这样写也是可以的:
<script>
const box = document.querySelector('.box')
console.log(box)
</script>
如果没有匹配到的话就返回null
选择匹配的多个元素语法:
<script>
const box = document.querySelectorAll('.box')
console.log(box)
</script>
参数包含一个或者多个有效的CSS选择器(字符串)
返回值:
CSS选择器匹配的NodeList对象集合
获取一个DOM元素我们使用querySelector()
这个我们获取到的是一个伪数组
有长度有索引号的数组
但是没有pop()、push()等数组方法
想要得到里面的每一个对象,则需要遍历for的方式获得
哪怕只有一个元素,通过querySelectAll()获取过来的也是一个伪数组,里面只有一个元素
案例:请控制台依次输出3个li的DOM对象
<!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>
<ul class="nav">
<li>我的首页</li>
<li>产品介绍</li>
<li>联系方式</li>
</ul>
<script>
const arr= document.querySelectorAll('ul li')
console.log(arr[0])
console.log(arr[1])
console.log(arr[2])
</script>
</body>
</html>
其他获取DOM元素方法
其他的方法我们了解即可:
操作元素内容
我们的目标是!能够修改元素的文本更换内容
DOM对象都是根据标签生成的,所以操作标签本质就是操作DOM对象
操作对象使用的点语法
如果想要修改标签元素里面的内容可以采取下面的方式:
1. 对象.innerText 属性
2. 对象.innerHTML 属性
<!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>
.info {
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<div class="info">
</div>
<script>
const info = document.querySelector('.info')
info.innerText = '小爷我就是陈俊男'
</script>
</body>
</html>
元素的innerText属性是将文本内容添加/更新到任意标签位置
显示纯文本,不解析标签
我听到了替罪的回响,小爷我就是陈俊男
元素.innerHTML属性
将文本内容添加/更新任意标签位置
会解析标签,多标签建议使用模板字符
<!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>
.info {
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<div class="info">
</div>
<script>
const info = document.querySelector('.info')
info.innerText = '小爷我就是陈俊男'
info.innerHTML = '小爷<strong>陈俊男</strong>,回响是穿墙'
</script>
</body>
</html>
年会抽奖案例
需求是从数组随机抽取一二三等奖,显示到对应的标签
素材是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>
<div class="wrapper">
<strong>终焉之地年会抽奖</strong>
<h1>一等奖:<span id="one">#???</span></h1>
<h1>二等奖:<span id="two">#???</span></h1>
<h1>三等奖:<span id="three">#???</span></h1>
</div>
<script>
const personArr = ['陈俊男','刘德华','张学友','周星驰','黎明']
let num1 = Math.floor(Math.random()*5)
const one = document.querySelector('#one')
one.innerHTML= personArr[num1]
personArr.splice(num1,1)
let num2 = Math.floor(Math.random()*4)
const two = document.querySelector('#two')
two.innerHTML= personArr[num2]
personArr.splice(num2,1)
let num3 = Math.floor(Math.random()*3)
const three = document.querySelector('#three')
three.innerHTML= personArr[num3]
personArr.splice(num3,1)
</script>
</body>
</html>
#是选id的意思
操作元素属性
操作元素常用属性
可以通过JS设置/修改标签元素属性,比如通过src更换图片
更常见的属性:href、title、src
练习:每次刷新页面都有新图片
<!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>
<img src="./01.jpg" alt="">
<script>
function getRandom(N, M) {
return Math.floor(Math.random() * (M - N + 1)) + N
}
const img = document.querySelector('img')
const random = getRandom(1, 4)
img.src = `./${random}.jpg`
</script>
</body>
</html>
操作元素样式属性
通过style属性操作CSS
可以通过JS设置/修改标签元素的样式属性
可以通过轮播图小圆点实现自动更换颜色样式
点击按钮可以滚动图片,这是移动图片的位置left等
语法是这样的:
修改元素样式属性通过style印出来
如果要修改一个div盒子的样式的话,就可以这样写(记得带单位)
让我们实现一个小案例,页面刷新就随机更换背景图片:
<!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>
body{
background: url(./1.jpg) no-repeat top center;
}
</style>
</head>
<body>
<script>
function getRandom(N, M) {
return Math.floor(Math.random() * (M - N + 1)) + N
}
const random = getRandom(1, 6)
document.body.style.backgroundImage = `url(./${random}.jpg)`
</script>
</body>
</html>
操作类名操作CSS
如果要修改的样式比较多的话,直接通过style属性修改比较繁琐,我们可以通过借助于CSS类名的形式
由于class是关键字,所以使用className去代替
className是使用新值换旧值,如果需要添加一个类,则需要保留之前的类名
<!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>
div{
width: 200px;
height: 200px;
background-color: pink;
}
.box{
width: 300px;
height: 300px;
background-color: skyblue;
margin: 100px auto;
padding: 10px;
border: 1px solid #000;
}
</style>
</head>
<body>
<div></div>
<script>
const div = document.querySelector('div')
div.className = 'box'
</script>
</body>
</html>
通过classList操作类控制CSS
为了解决className容易覆盖之前的类名,我们可以通过classList方式追加和删除类名
对象---属性---方法
这俩的区别说一下:
轮播图随机版
我们有着这样的需求:
我们的分析是如此的:
我们先修改一下图片,先获取随机数,再修改图片路径为对象里面的url
const random = parseInt(Math.random()*sliderData.length)
const img = document.querySelector(`.slider-wrapper img`)
// 修改图片路径为对象里面的url
img.src = sliderData[random].url
完整代码:
<!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>轮播图点击切换</title>
<style>
* {
box-sizing: border-box;
}
.slider {
width: 560px;
height: 400px;
overflow: hidden;
}
.slider-wrapper {
width: 100%;
height: 320px;
}
.slider-wrapper img {
width: 100%;
height: 100%;
display: block;
}
.slider-footer {
height: 80px;
background-color: rgb(100, 67, 68);
padding: 12px 12px 0 12px;
position: relative;
}
.slider-footer .toggle {
position: absolute;
right: 0;
top: 12px;
display: flex;
}
.slider-footer .toggle button {
margin-right: 12px;
width: 28px;
height: 28px;
appearance: none;
border: none;
background: rgba(255, 255, 255, 0.1);
color: #fff;
border-radius: 4px;
cursor: pointer;
}
.slider-footer .toggle button:hover {
background: rgba(255, 255, 255, 0.2);
}
.slider-footer p {
margin: 0;
color: #fff;
font-size: 18px;
margin-bottom: 10px;
}
.slider-indicator {
margin: 0;
padding: 0;
list-style: none;
display: flex;
align-items: center;
}
.slider-indicator li {
width: 8px;
height: 8px;
margin: 4px;
border-radius: 50%;
background: #fff;
opacity: 0.4;
cursor: pointer;
}
.slider-indicator li.active {
width: 12px;
height: 12px;
opacity: 1;
}
</style>
</head>
<body>
<div class="slider">
<div class="slider-wrapper">
<img src="./images/slider01.jpg" alt="" />
</div>
<div class="slider-footer">
<p>对人类来说会不会太超前了?</p>
<ul class="slider-indicator">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="toggle">
<button class="prev"><</button>
<button class="next">></button>
</div>
</div>
</div>
<script>
// 1. 初始数据
const sliderData = [
{ url: './images/slider01.jpg', title: '对人类来说会不会太超前了?', color: 'rgb(100, 67, 68)' },
{ url: './images/slider02.jpg', title: '开启剑与雪的黑暗传说!', color: 'rgb(43, 35, 26)' },
{ url: './images/slider03.jpg', title: '真正的jo厨出现了!', color: 'rgb(36, 31, 33)' },
{ url: './images/slider04.jpg', title: '李玉刚:让世界通过B站看到东方大国文化', color: 'rgb(139, 98, 66)' },
{ url: './images/slider05.jpg', title: '快来分享你的寒假日常吧~', color: 'rgb(67, 90, 92)' },
{ url: './images/slider06.jpg', title: '哔哩哔哩小年YEAH', color: 'rgb(166, 131, 143)' },
{ url: './images/slider07.jpg', title: '一站式解决你的电脑配置问题!!!', color: 'rgb(53, 29, 25)' },
{ url: './images/slider08.jpg', title: '谁不想和小猫咪贴贴呢!', color: 'rgb(99, 72, 114)' },
]
const random = parseInt(Math.random() * sliderData.length)
const img = document.querySelector(`.slider-wrapper img`)
// 修改图片路径为对象里面的url
img.src = sliderData[random].url
// 把p里面的文字内容更换
// 获取p
const p = document.querySelector('.slider-footer p')
// 修改p
p.innerHTML = sliderData[random].title
// 修改背景颜色
const footer = document.querySelector('.slider-footer')
footer.style.backgroundColor = sliderData[random].color
// 修改小圆点样式
const circle = document.querySelector(`.slider-indicator li:nth-child(${random + 1})`)
circle.classList.add('active')
</script>
</body>
</html>
操作表单元素属性
表单的很多情况下也需要修改属性,比如点击眼睛可以看到密码的本质是把表单类型转换成文本框
正常的有属性有取值的和其他的标签属性没有任何区别
获取:DOM对象.属性名
设置:DOM对象.属性名=新值
表单属性中添加就有效果,移除就没有效果,一律用布尔值表示,如果是true代表添加了该属性,如果是false代表移除了该属性
<!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>
<input type="password" name="" id="">
<script>
const password = document.querySelector('input')
password.value = '用户名'
password.type = 'text'
</script>
</body>
</html>
比如: disabled、checked、selected
自定义属性
标准属性是标签天生自带的属性,比如class id title等,可以直接用点语法操作:disabled、checked、selected
自定义属性:
在H5中退出了专门的data:自定义属性
在标签上一律以data-开头
在DOM对象上一律dataset对象方式获取
定时器-间歇函数
定时器函数介绍
定时器-间歇函数
目标:能够说出定时器函数在开发中的使用场景
网页中经常会需要一种功能,每隔一段时间需要自动执行一段代码,不需要我们去手动触发
例如:网页中的倒计时
要实现这种需求需要定时器函数
定时器函数有两种,间歇函数就是其中的一种
定时器函数基本使用
间歇函数的基本使用
目标:能够使用定时器函数重复执行代码
定时器函数可以开启和关闭定时器
开启定时器:
函数名字不要加括号,定时器返回的是一个id数字
关闭定时器:
定时器函数可以根据时间自动重复执行某些代码
阅读注册协议案例
需求:按钮60s之后才可以使用
分析:
一开始先把按钮禁用disable属性
获取元素,函数内处理逻辑:
秒数--,按钮里面的文字跟着一起变化
如果秒数为0,停止定时器,里面文字变为同意,按钮可以点击
<!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>我已经阅读用户协议(5)</button>
<script>
const btn = document.querySelector('.btn')
let i = 5
let n = setInterval(function () {
i--
btn.innerHTML = `我已经阅读用户协议(${i})`
if (i == 0) {
clearInterval(n)
btn.disabled = false
btn.innerHTML = '同意'
}
}, 1000)
</script>
</body>
</html>
综合案例
轮播图定时器版,需求:每隔一秒钟切换一个图片
分析:
大致和之前差不多,主要是添加定时器
<!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>轮播图点击切换</title>
<style>
* {
box-sizing: border-box;
}
.slider {
width: 560px;
height: 400px;
overflow: hidden;
}
.slider-wrapper {
width: 100%;
height: 320px;
}
.slider-wrapper img {
width: 100%;
height: 100%;
display: block;
}
.slider-footer {
height: 80px;
background-color: rgb(100, 67, 68);
padding: 12px 12px 0 12px;
position: relative;
}
.slider-footer .toggle {
position: absolute;
right: 0;
top: 12px;
display: flex;
}
.slider-footer .toggle button {
margin-right: 12px;
width: 28px;
height: 28px;
appearance: none;
border: none;
background: rgba(255, 255, 255, 0.1);
color: #fff;
border-radius: 4px;
cursor: pointer;
}
.slider-footer .toggle button:hover {
background: rgba(255, 255, 255, 0.2);
}
.slider-footer p {
margin: 0;
color: #fff;
font-size: 18px;
margin-bottom: 10px;
}
.slider-indicator {
margin: 0;
padding: 0;
list-style: none;
display: flex;
align-items: center;
}
.slider-indicator li {
width: 8px;
height: 8px;
margin: 4px;
border-radius: 50%;
background: #fff;
opacity: 0.4;
cursor: pointer;
}
.slider-indicator li.active {
width: 12px;
height: 12px;
opacity: 1;
}
</style>
</head>
<body>
<div class="slider">
<div class="slider-wrapper">
<img src="./images/slider01.jpg" alt="" />
</div>
<div class="slider-footer">
<p>对人类来说会不会太超前了?</p>
<ul class="slider-indicator">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="toggle">
<button class="prev"><</button>
<button class="next">></button>
</div>
</div>
</div>
<script>
// 1. 初始数据
const sliderData = [
{ url: './images/slider01.jpg', title: '对人类来说会不会太超前了?', color: 'rgb(100, 67, 68)' },
{ url: './images/slider02.jpg', title: '开启剑与雪的黑暗传说!', color: 'rgb(43, 35, 26)' },
{ url: './images/slider03.jpg', title: '真正的jo厨出现了!', color: 'rgb(36, 31, 33)' },
{ url: './images/slider04.jpg', title: '李玉刚:让世界通过B站看到东方大国文化', color: 'rgb(139, 98, 66)' },
{ url: './images/slider05.jpg', title: '快来分享你的寒假日常吧~', color: 'rgb(67, 90, 92)' },
{ url: './images/slider06.jpg', title: '哔哩哔哩小年YEAH', color: 'rgb(166, 131, 143)' },
{ url: './images/slider07.jpg', title: '一站式解决你的电脑配置问题!!!', color: 'rgb(53, 29, 25)' },
{ url: './images/slider08.jpg', title: '谁不想和小猫咪贴贴呢!', color: 'rgb(99, 72, 114)' },
]
const random = parseInt(Math.random() * sliderData.length)
const img = document.querySelector(`.slider-wrapper img`)
const p = document.querySelector('.slider-footer p')
const footer = document.querySelector('.slider-footer')
let i = 0
setInterval(function(){
i++
// 修改图片路径为对象里面的url
img.src = sliderData[i].url
// 把p里面的文字内容更换
p.innerHTML = sliderData[i].title
// 修改背景颜色
footer.style.backgroundColor = sliderData[i].color
// 修改小圆点样式
// 删除以前的active
// 只让当前li添加active
document.querySelector('.slider-indicator .active').classList.remove('active')
const circle = document.querySelector(`.slider-indicator li:nth-child(${i + 1})`)
circle.classList.add('active')
},1000)
</script>
</body>
</html>