事件监听(绑定)
事件是在编程时系统内发生的动作或者发生的事情,比如用户在网页上单击一个按钮。
事件监听就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为绑定事件或者注册事件。比如点击可以播放轮播图。
语法:
元素对象.addEventListener('事件类型',要执行的函数)
事件监听三要素:
- 事件源: 那个dom元素被事件触发了,要获取dom元素。
- 事件类型: 用什么方式触发,比如鼠标单击 click、鼠标经过 mouseover 等 。
- 事件调用的函数: 要做什么事。:
注意:
- 事件类型要加引号
- 函数是点击之后再去执行,每次点击都会执行一次。
点击关闭顶部广告
<div class="box">
我是广告
<div class="box1">X</div>
</div>
<script>
//获取事件源
const box1 = document.querySelector('.box1')
//关闭的使整个大盒子
const box = document.querySelector('.box')
//事件倾听
box1.addEventListener('click', function () {
box.style.display = 'none'
})
</script>
随机点名案例
<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>
//数据准备
const arr = ['马超', '黄忠', '赵云', '关羽', '张飞']
//定时器的全局变量
let timerId = 0
//随机random也要全局变量
let random = 0
//开始业务
const qs = document.querySelector('.qs')
//获取开始按钮对象
const start = document.querySelector('.start')
//添加点击事件
start.addEventListener('click', function () {
//自动变换,使用定时器
//timerId = setInterval(function () { 可以不声明,会被当做全局变量使用,但是不提倡
timerId = setInterval(function () {
random = parseInt(Math.random() * arr.length)
//修改内容
qs.innerHTML = arr[random]
}, 35)
//如果数组只剩下一个元素,就不需要再抽了且开始和结束按钮应处于禁用的状态
if (arr.length === 1) {
start.disabled = true
end.disabled = true
}
})
//关闭按钮
const end = document.querySelector('.end')
end.addEventListener('click', function () {
clearInterval(timerId)
// 结束应该删掉当前被抽取的元素
arr.splice(random, 1)
})
</script>
事件监听版本
DOM L0 事件源.on事件 = function() { } l
DOM L2 事件源.addEventListener(事件,事件处理函数)
区别: on方式会被覆盖,addEventListener方式可绑定多次,拥有事件更多特性,推荐使用。
事件类型
轮播图点击切换
<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>
// 初始数据
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 img = document.querySelector('.slider-wrapper img')
const p = document.querySelector('.slider-footer p')
const footer = document.querySelector('.slider-footer')
let i = 0 //全局信号量
//右侧按钮
const next = document.querySelector('.toggle .next')
next.addEventListener('click', function () {
i++
//如果大于数组的长度
if (i >= sliderData.length) {
i = 0
}
toggle()
})
//左侧按钮
const prev = document.querySelector('.toggle .prev')
prev.addEventListener('click', function () {
i--
if (i < 0) {
i = sliderData.length - 1
}
toggle()
})
//声明一个渲染函数,代码复用
function toggle() {
//渲染相应的数据
img.src = sliderData[i].url
p.innerHTML = sliderData[i].title
footer.style.backgroundColor = sliderData[i].color
//更换小圆点
//先删除以前的小圆点
document.querySelector('.slider-indicator .active').classList.remove('active')
//只让当前的Li添加小圆点
document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
}
//自动播放
let timerId = setInterval(function () {
//利用Js自动调用点击事件
next.click()
}, 1000)
//鼠标经过
const slider = document.querySelector('.slider')
slider.addEventListener('mouseenter', function () {
clearInterval(timerId)
})
slider.addEventListener('mouseleave', function () {
//关闭定时器
clearInterval(timerId)
//开启定时器,不需要let
timerId = setInterval(function () {
//利用Js自动调用点击事件
next.click()
}, 1000)
})
</script>
搜索框案例
<script>
const input = document.querySelector('[type=search]') //属性选择器
const ul = document.querySelector('.result-list')
//获取焦点
input.addEventListener('focus', function () {
ul.style.display = 'block'
input.classList.add('search')
})
//失去焦点
input.addEventListener('blur', function () {
ul.style.display = 'none'
input.classList.remove('search')
})
</script>
事件对象
事件对象:也是个对象,这个对象里有事件触发时的相关信息。例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息。
语法:
元素.addEventListener('click',function(e){})
注意:
(1)在事件绑定的回调函数的第一个参数就是事件对象
(2一般命名为event、ev、e
部分常用属性
str.trim()去除字符串两边的空格
评论回车发布
<script>
const tx = document.querySelector('#tx')
const total = document.querySelector('.total')
const item = document.querySelector('.item')
const text = document.querySelector('.text')
//文本域获得焦点时,total显示出来
tx.addEventListener('focus', function () {
total.style.opacity = 1
})
//文本域失去焦点时,total隐藏出来
tx.addEventListener('blur', function () {
total.style.opacity = 0
})
//检测用户输入
tx.addEventListener('input', function () {
total.innerHTML = `${tx.value.length}/200字`
})
//回车评论
tx.addEventListener('keyup', function (e) {
if (e.key === 'Enter') {
//if('') 等价于
if (tx.value.trim() !== '') {
item.style.display = 'block'
//获取用户输入的内容
text.innerHTML = tx.value
}
//结束完后文本域要清空
tx.value = ''
total.innerHTML = '0/200字'
}
})
</script>
环境对象
环境对象:指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境。
注意:
- 函数的调用方式不同,this 指代的对象也不同。
- 【谁调用, this 就是谁】 是判断 this 指向的粗略规则。
- 直接调用函数,其实相当于是 window.函数,所以 this 指代 window。
回调函数
定义:当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数。如setInterval(fn,1000)中的fn就是回调函数。
补充
为什么在事件监听中可以使用const random = Math.random()?
在函数内部有一个垃圾回收机制,如果函数的变量不再使用,就会被回收;下次再使用时会重新创建一个新的变量。
综合案例
Tab栏切换
//鼠标经过不同的选项卡,底部可以显示 不同的内容。
<div class="tab">
<div class="tab-nav">
<h3>每日特价</h3>
<ul>
<li><a class="active" href="javascript:;">精选</a></li>
<li><a href="javascript:;">美食</a></li>
<li><a href="javascript:;">百货</a></li>
<li><a href="javascript:;">个护</a></li>
<li><a href="javascript:;">预告</a></li>
</ul>
</div>
<div class="tab-content">
<div class="item active"><img src="./images/tab00.png" alt="" /></div>
<div class="item"><img src="./images/tab01.png" alt="" /></div>
<div class="item"><img src="./images/tab02.png" alt="" /></div>
<div class="item"><img src="./images/tab03.png" alt="" /></div>
<div class="item"><img src="./images/tab04.png" alt="" /></div>
</div>
</div>
<script>
//获取a元素
const as = document.querySelectorAll('.tab-nav a')
// 要给 5个链接绑定鼠标经过事件
for (let i = 0; i < as.length; i++) {
as[i].addEventListener('mouseenter', function () {
//排除其他 移除active
document.querySelector('.tab-nav .active').classList.remove('active')
// document.querySelector('.tab-nav a').classList.add('active')
// as[i].classList.add('active')
this.classList.add('active')
document.querySelector('.tab-content .active').classList.remove('active')
// 对应序号的那个 item 显示 添加 active 类
document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
})
}
</script>
同意协议
<script>
//获取元素
const registerBtn = document.querySelector('#registerBtn')
const agree = document.querySelector('#agree')
//添加事件
agree.addEventListener('click', function () {
//复选框选中是true,按钮启动disabled是false,则只要去相反就行
registerBtn.disabled = !this.checked
})
</script>
点击按钮切换
<input type="button" value="切换" id="btn"><br>
<img src="./images/1.jpg" alt="" width="300" id="img">
<script>
//数据准备
let arr = ['images/1.jpg', 'images/2.jpg', 'images/3.jpg', 'images/4.jpg', 'images/5.jpg', 'images/6.jpg']
//随机照片
function getRandom(min, max) {
return parseInt(Math.random() * (max - min + 1)) + min
}
//获取元素
let btn = document.querySelector('#btn')
let pic = document.querySelector('#img')
//注册事件
btn.addEventListener('click', function () {
let random = getRandom(0, arr.length - 1)
//src是属性不是样式,不用加style
pic.src = arr[random]
})
</script>
验证码
<ul>
<li>
手机号:
<input type="text">
</li>
<li>
验证码:
<input type="text" class="verify">
<button id="btn">获取验证码</button>
</li>
</ul>
<script>
//按钮
const btn = document.querySelector('#btn')
btn.addEventListener('click', function () {
//点击之后,禁止按钮,同时开启倒计时
this.disabled = true
//开启定时器
let i = 5 //定时器
btn.innerHTML = `${i}秒之后重新获得`
let timerId = setInterval(function () {
i--
// 在定时器里面不能用this,this执行的window
btn.innerHTML = `${i}秒之后重新获得`
//如果时间为0,则清除定时器,并且更改文字
if (i < 0) {
clearInterval(timerId)
btn.innerHTML = '获取验证码'
btn.disabled = false
}
}, 1000)
})
</script>
隐藏密码框
<!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>
.box {
position: relative;
width: 400px;
border-bottom: 1px solid #ccc;
margin: 100px auto;
}
.box input {
width: 370px;
height: 30px;
border: 0;
outline: none;
}
.box label {
position: absolute;
top: 2px;
right: 2px;
width: 24px;
height: 24px;
background-color: pink;
cursor: pointer;
background: url(./images/close.png) no-repeat;
background-size: cover;
}
//active类
.box label.active {
background-image: url(./images/open.png);
}
</style>
</head>
<body>
<div class="box">
<label for=""></label>
<input type="password" name="" id="pwd">
</div>
<script>
// 获取元素 label 和 input
const label = document.querySelector('label')
const input = document.querySelector('input')
// 给label 注册事件, 切换类实现图片的切换
// 声明一个变量来控制
let flag = true
label.addEventListener('click', function () {
this.classList.toggle('active')
// 因为要修改input的 type属性 text和password,可以使用一个变量来控制 flag , 如果为true 就切换为text ,如果为false就修改为 password
if (flag) {
input.type = 'text'
} else {
input.type = 'password'
}
//点击一次之后,flag的状态发生改变,开始时是true点击之后就应该是false
flag = !flag
})
</script>
</body>
</html>