Web APIs—事件监听、事件类型、事件对象、环境对象、回调函数、综合案例:随机点名案例,轮播图完整版,评论区回车发布,Tab栏切换
版本说明
当前版本号[20231205]。
版本 | 修改说明 |
---|---|
20231205 | 初版 |
目录
文章目录
Web APIs - 第2天
学会通过为DOM注册事件来实现可交互的网页特效。
- 能够判断函数运行的环境并确字 this 所指代的对象
- 理解事件的作用,知道应用事件的 3 个步骤
学习会为 DOM 注册事件,实现简单可交互的网页特交。
事件
事件是编程语言中的术语,它是用来描述程序的行为或状态的,一旦行为或状态发生改变,便立即调用一个函数。
例如:用户使用【鼠标点击】网页中的一个按钮、用户使用【鼠标拖拽】网页中的一张图片
事件监听
结合 DOM 使用事件时,需要为 DOM 对象添加事件监听,等待事件发生(触发)时,便立即调用一个函数。
就是让程序检测是否有事件产生,**一旦有事件触发,就立即调用一个函数做出响应,也称为绑定事件或者注册事件。**比如鼠标经过显示下拉菜单,比如点击可以播放轮播图等等
addEventListener
是 DOM 对象专门用来添加事件监听的方法,它的两个参数分别为【事件类型】和【事件回调】。
<body>
<h3>事件监听</h3>
<p id="text">为 DOM 元素添加事件监听,等待事件发生,便立即执行一个函数。</p>
<button id="btn">点击改变文字颜色</button>
<script>
// 1. 获取 button 对应的 DOM 对象
const btn = document.querySelector('#btn')
// 2. 添加事件监听
btn.addEventListener('click', function () {
console.log('等待事件被触发...')
// 改变 p 标签的文字颜色
let text = document.getElementById('text')
text.style.color = 'red'
})
// 3. 只要用户点击了按钮,事件便触发了!!!
</script>
</body>
</html>
完成事件监听分成3个步骤:
- 获取 DOM 元素
- 通过
addEventListener
方法为 DOM 节点添加事件监听 - 等待事件触发,如用户点击了某个按钮时便会触发
click
事件类型 - 事件触发后,相对应的回调函数会被执行
大白话描述:所谓的事件无非就是找个机会(事件触发)调用一个函数(回调函数)。
案例:通过点击按钮,弹出一个对话框
分析:
事件源: 按钮
事件类型: 点击鼠标 用 click 字符串
事件处理程序 弹出对话框
<body>
<button>点这点这!~</button>
<script>
const btn = document.querySelector('button')
btn.addEventListener('click', function(){
alert('Hello!~')
})
</script>
</body>
网页输出结果:
通过鼠标点击按钮后,会有弹出框的出现:
事件类型
click
译成中文是【点击】的意思,它的含义是监听(等着)用户鼠标的单击操作,除了【单击】还有【双击】dblclick
<script>
// 双击事件类型
btn.addEventListener('dblclick', function () {
console.log('等待事件被触发...');
// 改变 p 标签的文字颜色
const text = document.querySelector('.text')
text.style.color = 'red'
})
// 只要用户双击击了按钮,事件便触发了!!!
</script>
结论:【事件类型】决定了事件被触发的方式,如 click
代表鼠标单击,dblclick
代表鼠标双击。
事件处理程序
addEventListener
的第2个参数是函数,这个函数会在事件被触发时立即被调用,在这个函数中可以编写任意逻辑的代码,如改变 DOM 文本颜色、文本内容等。
<script>
// 双击事件类型
btn.addEventListener('dblclick', function () {
console.log('等待事件被触发...')
const text = document.querySelector('.text')
// 改变 p 标签的文字颜色
text.style.color = 'red'
// 改变 p 标签的文本内容
text.style.fontSize = '20px'
})
</script>
结论:【事件处理程序】决定了事件触发后应该执行的逻辑。
综合案例:随机点名案例
业务分析:
- 点击开始按钮随机抽取数组的一个数据,放到页面中
- 点击结束按钮删除数组当前抽取的一个数据
- 当抽取到最后一个数据的时候,两个按钮同时禁用(写点开始里面,只剩最后一个数据不用抽了)
- 核心:利用定时器快速展示,停止定时器结束展示
1、设计好开始页面。
2、设计事件监听器,功能是每点一次"开始"按钮就输出 ‘1’.
<script>
// 数据数组
const arr = ['马超', '黄忠', '赵云', '关羽', '张飞']
const start = document.querySelector('.start')
start.addEventListener('click', function(){
console.log(1)
})
</script>
3、设计事件监听器,每点击一次"开始"按钮,随机输出姓名。
<script>
……
const qs = document.querySelector('.qs')
……
start.addEventListener('click', function(){
const random = parseInt(Math.random() * arr.length)
qs.innerHTML = arr[random]
})
</script>
4、设计一个事件监听器,当用户点击按钮时,会每隔35毫秒随机选择一个数组元素并将其显示在页面上。
start.addEventListener('click', function(){
setInterval(function() {
const random = parseInt(Math.random() * arr.length)
qs.innerHTML = arr[random]
} ,35)
})
5、将局部变量变为全局变量,好让点击关闭按钮时,可以调用定时器,从而进行关闭。
<script>
let timeId = 0
timeId = setInterval(function() {
const random = parseInt(Math.random() * arr.length)
qs.innerHTML = arr[random]
} ,35)
})
const end = document.querySelector('.end')
end.addEventListener('click', function(){
clearInterval(timeId)
})
</script>
6、要想抽一个少一个,就得把随机变量变成全局变量,还得把const变为let。
<script>
// 数据数组
const arr = ['马超', '黄忠', '赵云', '关羽', '张飞']
const qs = document.querySelector('.qs')
let timeId = 0
let random = 0
const start = document.querySelector('.start')
start.addEventListener('click', function(){
timeId = setInterval(function() {
random = parseInt(Math.random() * arr.length)
qs.innerHTML = arr[random]
} ,35)
})
const end = document.querySelector('.end')
end.addEventListener('click', function(){
clearInterval(timeId)
arr.splice(random , 1)
console.log(arr)
})
</script>
7、判断数组arr
的长度是否为1,如果是,就是数组则将start
和end
两个按钮的disabled
属性设置为true
,表示这两个按钮被禁用。
start.addEventListener('click', function(){
……
if(arr.length === 1)
{
start.disabled = end.disabled = true
}
})
事件类型
将众多的事件类型分类可分为:鼠标事件、键盘事件、表单事件、焦点事件等,我们逐一展开学习。
鼠标事件
鼠标事件是指跟鼠标操作相关的事件,如单击、双击、移动等。
- `mouseenter 监听鼠标是否移入 DOM 元素
<body>
<h3>鼠标事件</h3>
<p>监听与鼠标相关的操作</p>
<hr>
<div class="box"></div>
<script>
// 需要事件监听的 DOM 元素
const box = document.querySelector('.box');
// 监听鼠标是移入当前 DOM 元素
box.addEventListener('mouseenter', function () {
// 修改文本内容
this.innerText = '鼠标移入了...';
// 修改光标的风格
this.style.cursor = 'move';
})
</script>
</body>
- `mouseleave 监听鼠标是否移出 DOM 元素
<body>
<h3>鼠标事件</h3>
<p>监听与鼠标相关的操作</p>
<hr>
<div class="box"></div>
<script>
// 需要事件监听的 DOM 元素
const box = document.querySelector('.box');
// 监听鼠标是移出当前 DOM 元素
box.addEventListener('mouseleave', function () {
// 修改文本内容
this.innerText = '鼠标移出了...';
})
</script>
</body>
键盘事件
keydown 键盘按下触发
keyup 键盘抬起触发
焦点事件
focus 获得焦点
blur 失去焦点
1、创建一个文本输入框,并使用JavaScript为该输入框添加了一个焦点事件监听器。当用户将焦点放在输入框上时,控制台会输出"有焦点触发"。
<body>
<input type="text">
<script>
const input = document.querySelector('input')
input.addEventListener('focus', function(){
console.log('有焦点触发')
})
</script>
</body>
2、为HTML元素添加事件监听器。作用是在用户将焦点从输入框移开时,在控制台输出"失去焦点触发"。
input.addEventListener('blur', function(){
console.log('失去焦点触发')
})
案例:搜索框
1、监听事件焦点。在网页中实现搜索框的自动聚焦功能。当用户点击页面上的搜索框时,搜索结果列表会显示出来。
<script>
const search = document.querySelector('[type=search]')
const list = document.querySelector('.result-list')
search.addEventListener('focus', function(){
list.style.display = 'block'
})
</script>
2、处理搜索框失去焦点(blur)的事件。当用户离开搜索框时,它会将列表的显示样式设置为’none’,即隐藏列表。
search.addEventListener('blur', function(){
list.style.display = 'none'
})
文本框输入事件
input
案例:评论字数统计
分析如下:
1、处理文本域获得焦点的事件。当用户在文本域中输入内容时,它会将右下角的显示记字数的框的透明度设置为1,使其可见。
<script>
// 当我们文本域获得焦点,就让total显示出来
const tx = document.querySelector('#tx')
const total = document.querySelector('.wrapper .total')
tx.addEventListener('focus', function(){
total.style.opacity = 1
})
</script>
2、当用户离开文本域时,它会将记字数的框的透明度设置为0,使其隐藏起来。
// 当我们文本域失去焦点,就让total隐藏出来
tx.addEventListener('blur', function(){
total.style.opacity = 0
})
3、用于检测用户在文本域中输入的内容。当用户在文本域中输入内容时,它会将文本域的值的长度输出到控制台,并将文本域的值的长度显示在名为"total"的元素中,同时限制文本域的最大长度为200字。
// 检测用户输入
tx.addEventListener('input', function(){
// 用于测试输出长度是否一致
console.log('1')
total.innerHTML = `${tx.value.length}/200字`
})
综合案例:轮播图完整
需求:当点击左右的按钮,可以切换轮播图
1、设置右按钮业务。
// 右按钮业务
// 获取右侧按钮
const next = document.querySelector('.next')
// 注册点击事件
next.addEventListener('click', function() {
console.log(11)
})
连续点击几次后:
2、增加信号量 i , 得到对应的对象出来。
……
// 信号量,用于控制播放图片张数
let i = 0
// 注册点击事件
next.addEventListener('click', function() {
i++
// 得到对应的对象出来
console.log(data[i])
})
3、让原先的img中的src不断替换数据源中的url图片,从而形成切换图片的样式。
// 获取元素
const img = document.querySelector('.slider-wrapper img')
// 右按钮业务
// 获取右侧按钮
const next = document.querySelector('.next')
// 信号量,用于控制播放图片张数
let i = 0
// 注册点击事件
next.addEventListener('click', function() {
i++
// 得到对应的对象出来
//
img.src = data[i].url
})
4、获取文字。
// 获取元素
const p = document.querySelector('.slider-footer p')
……
next.addEventListener('click', function() {
i++
// 得到对应的对象出来
// 文字类一定要加上 innerHTML 才能显示出来!
p.innerHTML = data[i].title
})
5、切换背景。
// 获取元素
const color = document.querySelector('.slider-footer')
next.addEventListener('click', function() {
i++
……
// 背景颜色的命名要记得是小驼峰命名法!
color.style.backgroundColor = data[i].color
})
6、设计小圆点样式。
// 添加小圆点
// 先移除原来的类名,再给当前 li 再添加 这个 类名
document.querySelector('.slider-indicator .active').classList.remove('active')
document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
7、如果大于等于8,则复原成0,从头再开始遍历图片。
// 判断条件
if(i >= data.length)
{
i = 0
}
8、增加左按钮业务,功能也是左右切换图片。
// 左按钮业务
// 获取左侧按钮
const prev = document.querySelector('.prev')
// 注册点击事件
prev.addEventListener('click', function() {
i--
// 判断条件
if(i < 0)
{
i = data.length - 1
}
// 得到对应的对象出来
img.src = data[i].url
// 文字类一定要加上 innerHTML 才能显示出来!
p.innerHTML = data[i].title
// 背景颜色的命名要记得是小驼峰命名法!
color.style.backgroundColor = data[i].color
// 添加小圆点
// 先移除原来的类名,再给当前 li 再添加 这个 类名
document.querySelector('.slider-indicator .active').classList.remove('active')
document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
})
9、学会调用该函数。
// 声明一个渲染的函数作为复用
function common()
{
// 得到对应的对象出来
img.src = data[i].url
// 文字类一定要加上 innerHTML 才能显示出来!
p.innerHTML = data[i].title
// 背景颜色的命名要记得是小驼峰命名法!
color.style.backgroundColor = data[i].color
// 添加小圆点
// 先移除原来的类名,再给当前 li 再添加 这个 类名
document.querySelector('.slider-indicator .active').classList.remove('active')
document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
}
// 如需调用公共函数,示例如下:
common()
10、使用了setInterval
函数来定时执行一个匿名函数,该函数会模拟点击名为"next"的元素。
// 自动播放模块
let nameId = setInterval(function(){
// 利用js自动调用点击事件,一定要加小括号来调用函数
next.click()
}, 1000)
11、用于在鼠标经过名为"slider"的元素时停止计时器。
// 鼠标经过,停止计时器
const slider = document.querySelector('.slider')
slider.addEventListener('mouseenter', function(){
clearInterval(nameId)
})
12、用于在鼠标离开名为"slider"的元素时重新开启计时器。
// 鼠标离开,打开计时器
slider.addEventListener('mouseleave', function(){
clearInterval(nameId)
// 自动播放模块,不要把let加进来,那样就是局部变量了
nameId = setInterval(function(){
// 利用js自动调用点击事件,一定要加小括号来调用函数
next.click()
}, 1000)
})
事件对象
任意事件类型被触发时与事件相关的信息会被以对象的形式记录下来,我们称这个对象为事件对象。
事件对象是什么?
- 也是个对象,这个对象里有事件触发时的相关信息
- 例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息
使用场景
- 可以判断用户按下哪个键,比如按下回车键可以发布新闻
- 可以判断鼠标点击了哪个元素,从而做相应的操作
语法:如何获取
- 在事件绑定的回调函数的第一个参数就是事件对象
- 一般命名为event、ev、e
<body>
<h3>事件对象</h3>
<p>任意事件类型被触发时与事件相关的信息会被以对象的形式记录下来,我们称这个对象为事件对象。</p>
<hr>
<div class="box"></div>
<script>
// 获取 .box 元素
const box = document.querySelector('.box')
// 添加事件监听
box.addEventListener('click', function (e) {
console.log('任意事件类型被触发后,相关信息会以对象形式被记录下来...');
// 事件回调函数的第1个参数即所谓的事件对象
console.log(e)
})
</script>
</body>
事件回调函数的【第1个参数】即所谓的事件对象,通常习惯性的将这个对数命名为 event
、ev
、ev
。
接下来简单看一下事件对象中包含了哪些有用的信息:
ev.type
当前事件的类型ev.clientX/Y
光标相对浏览器窗口的位置ev.offsetX/Y
光标相于当前 DOM 元素的位置
注:在事件回调函数内部通过 window.event 同样可以获取事件对象。
1、用于监听键盘按键释放事件。当用户在输入框中按下并释放一个键时,会触发这个事件。
input.addEventListener('keyup', function(e){
console.log(e)
})
2、而我们刚刚输入的键,可通过 key 拿到。
3、e.key 代表是我们输入的按键内容。
input.addEventListener('keyup', function(e){
console.log(e.key)
})
4、在用户在网页上的输入框中按下回车键时,控制台会输出"回车!"。
<script>
const input = document.querySelector('input')
input.addEventListener('keyup', function(e){
if(e.key === 'Enter'){
console.log('回车!')
}
})
</script>
案例:评论回车发布
需求:按下回车键盘,可以发布信息
分析如下:
参考输出:
1、在用户在输入框(假设其ID为"tx")中按下回车键时,将具有类名"item"的元素(即回复框)显示出来。
const list = document.querySelector('.item')
tx.addEventListener('keyup', function(e){
if(e.key === 'Enter')
{
list.style.display = 'block'
}
})
2、是在用户在输入框(假设其ID为"tx")中按下回车键时,将输入框的值显示在具有类名"info .text"的元素中,并将该元素设置为可见。
const list = document.querySelector('.item')
const text = document.querySelector('.info .text')
tx.addEventListener('keyup', function(e){
if(e.key === 'Enter')
{
list.style.display = 'block'
text.innerHTML = tx.value
}
})
3、这段代码是一个事件处理函数,用于处理键盘按键事件。当用户按下回车键时,会执行以下操作:
- 首先,检查文本框(tx)的值是否为空或只包含空格。如果是空的或者只包含空格,则不执行任何操作。
- 如果文本框的值不为空且不仅包含空格,则将文本框的值显示在列表元素(list)中,并将其设置为可见状态。
- 最后,清空文本框的值,以便用户可以继续输入新的文本。
if(e.key === 'Enter')
{
if(tx.value.trim() !== '')
{
// 如果用户输入的不为空就显示和打印
list.style.display = 'block'
text.innerHTML = tx.value
}
// 按下回车清空文本域
tx.value = ''
}
环境对象
能够分析判断函数运行在不同环境中 this 所指代的对象。
环境对象指的是函数内部特殊的变量 this
,它代表着当前函数运行时所处的环境。
<script>
// 声明函数
function sayHi() {
// this 是一个变量
console.log(this);
}
// 声明一个对象
let user = {
name: '张三',
sayHi: sayHi // 此处把 sayHi 函数,赋值给 sayHi 属性
}
let person = {
name: '李四',
sayHi: sayHi
}
// 直接调用
sayHi() // window
window.sayHi() // window
// 做为对象方法调用
user.sayHi()// user
person.sayHi()// person
</script>
结论:
this
本质上是一个变量,数据类型为对象- 函数的调用方式不同
this
变量的值也不同 - 【谁调用
this
就是谁】是判断this
值的粗略规则 - 函数直接调用时实际上
window.sayHi()
所以this
的值为window
回调函数
如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数。
目标:能够说出什么是回调函数
如果将函数A做为参数传递给函数B时,我们称函数A为回调函数
简单理解:当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数
function bar() {
console.log('函数也能当参数...');
}
foo(bar);
函数 bar
做参数传给了 foo
函数,bar
就是所谓的回调函数了!!!
我们回顾一下间歇函数 setInterval
<script>
function fn() {
console.log('我是回调函数...');
}
// 调用定时器
setInterval(fn, 1000);
</script>
fn
函数做为参数传给了 setInterval
,这便是回调函数的实际应用了,结合刚刚学习的函数表达式上述代码还有另一种更常见写法。
<script>
// 调用定时器,匿名函数做为参数
setInterval(function () {
console.log('我是回调函数...');
}, 1000);
</script>
结论:
- 回调函数本质还是函数,只不过把它当成参数使用
- 使用匿名函数做为回调函数比较常见
综合案例:Tab栏切换
鼠标经过不同的选项卡,底部可以显示不同的内容
分析如下:
1、每次鼠标滑动经过一次,就增加一次输出“11”。
记得这里要使用: querySelectorAll ! 因为要把5个 a 全部拿过来!
<script>
const as = document.querySelectorAll('.tab-nav a')
for(let i = 0 ; i < as.length; i++)
{
as[i].addEventListener('mouseenter', function(){
console.log("11")
})
}
</script>
2、首先先移除类active。可以看到,第一次移除时不会出现任何的问题,第二次因为没有 active 给他移除了,就直接报错了。
as[i].addEventListener('mouseenter', function(){
// 排他思想
// 移除类active
document.querySelector('.tab-nav .active').classList.remove('active')
})
3、给当前的 a 添加上类 active 。就可以随意改样式啦。
// 添加类active this 即代表当前的这个
this.classList.add('active')
4、修改图片。可以看到,第一次移除时不会出现任何的问题,第二次因为没有 active 给他移除了,就直接报错了。
// 改图片
// 移除类active
document.querySelector('.tab-content .active').classList.remove('active')
5、是为页面上对应索引的标签内容项添加一个名为 “active” 的类。具体来说,它使用 querySelector
方法选择具有特定 CSS 选择器的元素,然后使用 classList.add
方法将 “active” 类添加到该元素的类列表中。从而实现每一选项内的图片都可以进行更换。
// 对应符号的那个 item 表示,添加 active 类
document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!