day2事件基础
文章目录
目标:
- 能给元素添加事件
- 利用事件做常见的网页交互效果
什么是事件?
- 事件是在编程时系统内发生的动作或者发生的事情
- 比如用户在网页上单击一个按钮
1、事件监听
什么是事件监听?
就是网页上点击了一个按钮,就会触发另外一个事件发生。这里说清楚点就是:一旦有事件触发,就立即调用一个函数做出响应,也称为注册事件
元素.addEventListener('事件',要执行的函数)
事件监听三要素:
事件源:那个dom元素被事件触发了,要获取dom元素
事件:用什么方式触发,比如鼠标单击click、鼠标经过mouseover等
事件调用函数:要做什么事
案例:随机点名
需求:点击开始随机抽取,点击结束输出结果
业务分析:
① 点击开始按钮随机抽取数组的一个数据,放到页面中
② 点击结束按钮删除数组当前抽取的一个数据
③ 当抽取到最后一个数据的时候,两个按钮同时禁用
核心:利用定时器快速展示,停止定时器结束展示
<!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>
div {
width: 200px;
height: 40px;
border: 1px solid skyblue;
text-align: center;
line-height: 40px;
}
</style>
</head>
<body>
<div></div>
<button class="start">开始</button>
<button class="end">结束</button>
<script>
// 1.获取元素div和button
let box = document.querySelector('div')
let start = document.querySelector('.start')
let end = document.querySelector('.end')
//2. 随机函数
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
// 声明数组
let arr = ['小王', '王忠', '张飞', '马超', '曹操', 'ping老师']
// 3.事件监听
// let name = btn.addEventListener('click', function () {
// // 4.实现名字快速略过:间歇器
let timer = 0
let random = arr[0]
// 4.给开始按钮注册事件
start.addEventListener('click', function () {
timer = setInterval(function () {
//注意: 随机数字 小驼峰命名
random = getRandom(0, arr.length - 1)
box.innerHTML = arr[random]
// 删除数组里的元素
}, 100)
// 6. 如果数组里面剩下最后一个,就要禁用按钮
if (arr.length === 1) {
// 对象属性不熟悉
start.disabled = true
end.disabled = true
}
})
// 5.给结束按钮注册事件,本质停止定时器
end.addEventListener('click', function () {
clearInterval(timer)
arr.splice(random, 1)
})
// 没有反应?没有名字出现 29行Math.floor中的Math写成小写了(注意看报错信息)
</script>
</body>
</html>
2、拓展阅读-事件监听版本
事件监听版本
- DOM L0
事件源.on事件 = function() { }
- DOM L2
事件源.addEventListener(事件, 事件处理函数)
- 发展史:
DOM L0 :是 DOM 的发展的第一个版本; L:level
DOM L1:DOM级别1 于1998年10月1日成为W3C推荐标准
DOM L2:使用addEventListener注册事件
DOM L3: DOM3级事件模块在DOM2级事件的基础上重新定义了这些事件,也添加了一些新事件类型
3、事件类型
3.1事件类型
- 鼠标事件(鼠标触发):click-鼠标点击、mouseenter-鼠标经过、mouseleave-鼠标离开
- 焦点事件(表单获得光标):focus-获得焦点、blus-失去焦点
- 键盘事件(键盘触发):Keydown-键盘按下触发、Keyup-键盘抬起触发
- 文本事件(表单输入触发):input-用户输入事件
案例1:微博输入
需求:用户输入文字,可以计算用户输入的字数
分析:
①:判断用输入事件 input
②:不断取得文本框里面的字符长度
③:把获得数字给下面文本框
<!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>
<link rel="stylesheet" href="css/weibo.css">
</head>
<body>
<div class="w">
<div class="controls">
<img src="images03/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>
// 1.获取元素
let area = document.querySelector('#area')
let useCount = document.querySelector('.useCount')
// 2.绑定事件,用户输入事件input
area.addEventListener('input', function () {
// area.value.length 得到输入字符的长度
useCount.innerHTML = area.value.length
})
</script>
</body>
</html>
图1
案例2:全选文本框
需求:用户点击全选,则下面复选框全部选择,取消全选则全部取消,文字对应变化
分析:
①:遍历下面的所有的checkbox,添加点击事件
②:在事件内部,遍历所有的checkbox状态,只要有一个为false 就将全选状态设置为false , 把文字改
为全选,并且直接return (退出循环)
③:在循环结束将全选的状态直接设置为true
<!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;
}
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>
let all = document.querySelector('#checkAll')
let cks = document.querySelectorAll('.ck')
let span = document.querySelector('.all')
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 = '全选'
}
})
// 核心部分:想通
// 遍历三个小按钮,添加点击事件
for (let i = 0; i < cks.length ; i++) {
// 绑定事件
cks[i].addEventListener('click', function () {
// 循环判断:如果有一个为false,就将all设为“全选”
for (let j = 0; j < cks.length; j++) {
// 如果这段没有生效,看看哪儿是不是写漏了
if (cks[j].checked === false) {
all.checked = false
span.innerHTML = '全选'
// 如果没有全部为false,就退出function
// return退出函数
return
}
}
// 如果代码来到了这里,说明三个小按钮都点上了,就自动给all改为true
all.checked = true
span.innerHTML = '取消'
})
}
</script>
</body>
</html>
案例2:购物车加减操作
需求:用户点击加号,则文本框+1,点击减号,则文本框-1,如果文本框为1,则禁用减号
分析:
①:给添加按钮注册点击事件, 获取表单的value,然后自增
②:解除减号的disabled状态
③:给减号按钮添加点击事件,获取表单的value,然后自减
④:自减结束需要判断,如果结果小于等于1 则添加上disabled状态
<!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: 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="1" readonly>
<input type="button" value="+" id="add">
<input type="button" value="-" id="reduce" disabled>
<script>
// 1. 获取元素 三个
let total = document.querySelector('#total')
let add = document.querySelector('#add')
let reduce = document.querySelector('#reduce')
// 2. 点击加号 事件侦听
add.addEventListener('click', function () {
// console.log(typeof total.value)
// total.value = total.value + 1
// i++ 隐式转换
// i = i + 1
total.value++
reduce.disabled = false
})
// 3. 点击减号 事件侦听
reduce.addEventListener('click', function () {
total.value--
if (total.value <= 1) {
reduce.disabled = true
}
})
// 2 === '2'
</script>
</div>
</body>
</html>
4、高阶函数
理解:高阶函数可以被简单理解为函数的高级应用,JavaScript 中函数可以被当成【值】来对待,基于这个特性实现函数的高 级应用。
高阶函数:
- 函数表达式
- 回调函数
4.1函数表达式
就是函数被当成值赋给一个变量,这个函数就称为高阶函数
,普通函数声明调用无顺序限制,只是更推荐先声明再调用。函数表达式必须先声明后调用
4.2回调函数
如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数
简单理解: 当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数
回调函数本质还是函数,只是把它当成参数使用;使用匿名函数做为回调函数比较常见
5、环境对象
目标:能够分析判断函数运行在不同环境中 this 所指代的对象
概念:环境对象指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境
作用:弄清楚this的指向,可以让我们代码更简洁
- 函数的调用方式不同,this 指代的对象也不同
- 【谁调用, this 就是谁】 是判断 this 指向的粗略规则
- 直接调用函数,其实相当于是 window.函数,所以 this 指代 window
6、编程思想(排他思想)
概念:当前元素为A状态,其他元素为B状态
使用:
- 干掉所有人
使用for循环
- 复活他自己
通过this或者下标找到自己或者对应的元素
案例: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>
// 0. 获取元素
// 得到所有的小li
let lis = document.querySelectorAll('.tab .tab-item')
let divs = document.querySelectorAll('.products .main')
// 1. 头部tab栏切换模块
// 1.1 先给4个小li添加点击事件
for (let i = 0; i < lis.length; i++) {
lis[i].addEventListener('click', function () {
// console.log(11)
// 找到以前的active 类,移除掉
document.querySelector('.tab .active').classList.remove('active')
// 当前的元素添加
this.classList.add('active')
// 2. 底部显示隐藏模块 一定要写到点击事件的里面
document.querySelector('.products .active').classList.remove('active')
// div对应序号的那个加上active
divs[i].classList.add('active')
})
}
</script>
</body>
</html>