1 事件概述
1.什么是事件?
1.事件是在编程时系统内发生的动作或者发生的事情 比如用户在网页上单击一个按钮
2.什么是事件监听?
1.就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为 注册事件
3.语法
元素.addEventListener('事件',要执行的函数)
btn1.addEventListener('click', function () {
console.log('开始抽奖啦');
});
4.事件监听三要素:
1.事件源: 那个dom元素被事件触发了,要获取dom元素
2.事件: 用什么方式触发,比如鼠标单击 click、鼠标经过 mouseover 等
3.事件调用的函数: 要做什么事
5.案列
//1.获取元素
let html= document.querySelector('html')
//2.事件监听 (注册事件)
html.addEventListener('mousemove',function () {
console.log('潮吧肖耀');
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>05-事件初体验.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
div {
height: 300px;
background-color: aqua;
}
</style>
</head>
<body>
<button class="btn1">抽奖</button>
<button class="btn2">退出抽奖</button>
<div></div>
<script>
/*
触发事件dom元素
事件类型
事件触发了 做业务 函数
*/
let btn1 = document.querySelector('.btn1');
// 注册事件
// btn1.addEventListener("事件类型","处理函数")
// click 鼠标单击
btn1.addEventListener('click', function () {
console.log('开始抽奖啦');
});
let btn2 = document.querySelector('.btn2');
btn2.addEventListener('click', function () {
console.log('退出抽奖啦');
});
let div = document.querySelector('div');
// mouseover 鼠标移入到 div 的区域内
div.addEventListener('mouseover', function () {
console.log('小哥快点进来');
});
let html= document.querySelector('html')
html.addEventListener('mousemove',function () {
console.log('潮吧肖耀');
})
</script>
</body>
</html>
2.事件基础
1.JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为
2.简单理解: 触发--- 响应机制。
3.网页中的每个元素都可以产生某些可以触发 JavaScript 的事件,例如,我们可以在用户点击某按钮时产生一个 事件,然后去执行某些操作
4.案列
//页面中有一个按钮,当鼠标点击按钮的时候,弹出“你好”警示框。
/*
1.获取事件源(按钮)
2.注册事件(绑定事件),使用 onclick
3.添加事件处理程序(采取函数赋值形式)
(编写事件处理程序,写一个函数弹出 alert 警示框)
*/
<buttton class="btn">点我</button>
var btn = document.getElementById('.btn');
btn.onclick = function() {
alert('你好吗');
};
2.常见的鼠标事件
2.常见的鼠标事件
| 鼠标事件 | 触发条件 |
|---|---|
| click | 鼠标点击左键触发 |
| mouseover ,mouseenter | 鼠标经过触发 |
| mouseout ,mouseleave | 鼠标离开触发 |
| focusr | 获得鼠标焦点触发 |
| blur | 失去鼠标焦点触发 |
| mousemove | 鼠标移动触发 |
| mouseup | 鼠标弹起触发 |
| mousedown | 鼠标按下触发 |
| contextmenu | 用户点击鼠标右键打开上下文菜单时触发 |
| dblclick | 鼠标双击左键 |
3.焦点事件
| 焦点事件 | 表单获得光标 |
|---|---|
| focus | 获得焦点 |
| blur | 失去焦点 |
4.键盘事件
| 键盘事件 | 键盘触发 |
|---|---|
| Keydown | 键盘按下触发 |
| Keyup | 键盘抬起触发 |
| keypress | 键盘按键被按下并松开 |
5.文本事件
| 文本事件 | 表单输入触发 |
|---|---|
| input | 用户输入事件 |
3.高级函数
高阶函数可以被简单理解为函数的高级应用,JavaScript 中函数可以被当成【值】来对待,基于这个特性实现函数的高级应用。
【值】就是 JavaScript 中的数据,如数值、字符串、布尔、对象等。
1 函数表达式
1.函数表达式和普通函数并无本质上的区别:
数也是【数据】 把函数赋值给变量
//函数表达式与普通函数本质上是一样的
let counter = function (x,y){
return x + y
}
//调用函数
let resule = counter(5,10)
console.log(result)
//普通函数的声明与调用无顺序限制,推荐做法先声明再调用
//函数表达式必须要先声明再调用
2.函数回调
如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数
简单理解:当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数
function fn () {
console.log('我是回调函数')
}
//fn传递给 setInterval,fun就是函数回调
setInterval(fn,1000)
box.addEventListener('click' , function(){
console.log('我也是回调函数')
})
把函数当做另外一个函数的参数传递,这个函数就叫回调函数
回调函数本质还是函数,只不过把它当成参数使用
使用匿名函数做为回调函数比较常见
4.环境对象
环境对象指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境
1.作用:
1.弄清楚this的指向,可以让我们代码更简洁
2.函数的调用方式不同,this 指代的对象也不同
3.【谁调用, this 就是谁】 是判断 this 指向的粗略规则
4.直接调用函数,其实相当于是 window.函数,所以 this 指代 window
5.排他思想
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>06-怕他思想的应用.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
width: 600px;
height: 100px;
display: flex;
margin: 100px auto;
border: 1px solid #ccc;
}
li {
display: flex;
flex: 1;
align-items: center;
justify-content: center;
font-size: 30px;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
// 先获取到每一个li标签
// 再li标签绑定点击事件
// 写处理其他所有的元素 让让他们的背景颜色都变成白色
// 事件触发 设置 被点击的li标签 选中的样式
// let liList = document.querySelectorAll('li');
// for (let index = 0; index < liList.length; index++) {
// liList[index].addEventListener('click', function () {
// // 给被点击的li标签加上选中样式
// // liList[index].style.backgroundColor = 'red';
// // 先设置每一个li标签的背景颜色 成 白色
// for (let j = 0; j < liList.length; j++) {
// liList[j].style.backgroundColor = '#fff';
// }
// // 再单独设置 被点击的li标签 变成红色
// this.style.backgroundColor = 'red';
// });
// }
let liList = document.querySelectorAll('li'); // 获取所有的li标签 数组
for (let index = 0; index < liList.length; index++) {
// 对所有的li标签 开始绑定点击事件
liList[index].addEventListener('click', function () {
// 设置所有的li标签 背景颜色为白色
setAllLiColor();
// 设置被点击的li标签 为红色
this.style.backgroundColor = 'red';
});
}
// 设置所有li标签的背景颜色为白色
function setAllLiColor() {
for (let j = 0; j < liList.length; j++) {
liList[j].style.backgroundColor = '#fff';
}
}
</script>
</body>
</html>
6.综合案列
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>
</head>
<body>
<h1></h1>
<button class="btn1">开始随机点名</button>
<button class="btn2">结束点名</button>
<script>
/*
优化
1 把数组的定义 提取到外面
2 如果定时器中业务比较繁琐 也可以提取出去到单独函数中 不是必须
3 bug 点击多次 开始抽奖 ,后面无法停止定时器
在我们行业中 有专业的术语 节流!!
让我们的顺序 一一个的执行 一次一次的执行 不要同时执行多个
在一个定时器没有执行结束的时候 不让开启另外一个定时器
一个班级的人 都想去上厕所 !!
你想要去上厕所的时候
1 先看一下里面有没有人
2 有人了 我就不去
3 没有人 我进去了 会把门关上
4 解决完毕了 出去同时把门打开
4 如何解决 点击多次按钮 后面停止定时器的bug n种解法
1 在开启定时器的时候 我直接禁用了button 不让它再次点击
在清除定时器 重新启用按钮即可
2 在每一次开启定时器的之前,都停止一次定时器
5 同学思考
是否可以理解 老师说 你的案例写不够多的时候 不可能一写就写出来 简洁的代码
1 给时间你去练习 先自己写一写 感受一下 (写出来 写不出来 无所谓 )
2 到老师开始讲解案例
1 吸收老师写案例的 思路、代码编写顺序、习惯、 业务逻辑
2 当场就理解老师的案例 (不够清晰、不够熟练)
3 晚自习或者休息天 时候 继续 巩固使用 熟悉它
*/
let btn1 = document.querySelector('.btn1');
let btn2 = document.querySelector('.btn2');
let h1 = document.querySelector('h1');
let arr = ['张飞', '赵云', '刘备', '吕布', '刘婵'];
let timeId;
// 定时器要执行的业务逻辑
function intervalDo() {
let index = Math.round(Math.random() * (arr.length - 1));
h1.innerText = arr[index];
// return undefined
}
btn1.addEventListener('click', function () {
// 先停止定时器 第一次清除 定时器的时候 timeId 是undefined
// if (timeId) {
if (timeId !== undefined) {
// timeId = 是 undefined => bool 是false
// 当timeId = undefined =false 不满足条件 不会执行 清除了
clearInterval(timeId);
}
// 禁用按钮 不让再次点击
// btn1.disabled = true;
timeId = setInterval(intervalDo, 100);
console.log('开启定时器', timeId);
});
btn2.addEventListener('click', function () {
// 重新启用 开始按钮
// btn1.disabled = false;
clearInterval(timeId);
});
</script>
</body>
</html>
2.全选打勾全选取消
<!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 () {
// console.log(all.checked) // true false
// 我们需要做的就是把 all.checked 给下面三个小按钮
// 因为三个按钮在伪数组里面,我们需要遍历的方式,挨着取出来,依次给值
for (let i = 0; i < cks.length; i++) {
cks[i].checked = all.checked
}
// 当我们的全选按钮处于选中状态,则可以改为取消
if (all.checked) {
// console.log('要改')
span.innerHTML = '取消'
} else {
span.innerHTML = '全选'
}
})
// 3. 小按钮的做法 同时给多个元素绑定相同事件
for (let i = 0; i < cks.length; i++) {
// 绑定事件
cks[i].addEventListener('click', function () {
// console.log(11)
// 只要点击任何一个小按钮,都要遍历所有的小按钮
for (let j = 0; j < cks.length; j++) {
// 都来看看是不是有人没有选中
if (cks[j].checked === false) {
// 如果有false 则退出循环 结束函数
all.checked = false
span.innerHTML = '全选'
return
}
}
// 当我们的循环结束,如果代码走到这里,说明没有false,都被选中了,则全选按钮要选中
all.checked = true
span.innerHTML = '取消'
})
}
</script>
</body>
</html>
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>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 () {
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.小米搜索框
<!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;
}
.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="#">小米11</a></li>
<li><a href="#">小米10S</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>
//1. 获取元素
let search =document.querySelector('input') //input表单
let list =document.querySelector('.result-list') //下拉菜单
//2.事件监听 获得光标事件 focus
search.addEventListener('focus',function () {
//显示下拉菜单
search.classList.add('search')
//文本框变色
list.style.display = 'block'
} )
//3.事件监听 失去光标事件
search.addEventListener('blur',function () {
//隐藏下拉菜单
search.classList.remove('search')
//文本框去色
list.style.display = 'none'
} )
</script>
</body>
</html>
5.微博输入案列 基础
<!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>
//1.获取元素
let area =document.querySelector('#area') //文本域
let useCount =document.querySelector('.useCount') // 0
//2.事件监听 用户输入事件 input
area.addEventListener('input',function () {
//不断得到文本域里面的字符长度
//area.value 可以得到用户输入的值
//area.value.length //得到用户输入的值的长度
useCount.innerHTML=area.value.length
})
</script>
</body>
</html>
6.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 li =document.querySelectorAll('.tab-item') //获取所有li标签
let div = document.querySelectorAll('.products .main') //获取prducts 里面的所有 main标签
// console.log(li);
// console.log(div);
for (let index = 0; index < li.length; index++) { //循环所有li标签
li[index].addEventListener('click',function () { //点击事件
document.querySelector('.active').classList.remove('active') //所有标签去掉红色上边框
this.classList.add('active') //自己添加红色上边框
//去掉products标签里面的 active标签
document.querySelector('.products .active').classList.remove('active')
//给products标签里面的 div添加 active标签
div[index].classList.add('active')
})
}
</script>
</body>
</html>