一,事件监听
1.1 事件监听概述
-
什么是事件?
事件是在编程时系统内发生的动作或者发生的事情
比如用户在网页上单击一个按钮 -
什么是事件监听?
就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为 绑定事件或者注册事件
比如鼠标经过显示下拉菜单,比如点击可以播放轮播图等等 -
语法
元素对象.addEventListener('事件类型',要执行的函数) -
事件监听三要素
- 事件源:哪个dom元素被事件触发了,要获取dom元素
- 事件类型:用什么方式触发,比如鼠标单击click,鼠标经过mouseover等
- 事件调用的函数:要做什么事情
-
举例
<button> 按钮 </button> <script> const btn = document.querySelector('.btn') //修改元素样式 btn.addEventListener('click',function(){ alert('点击') }) </script>
1.2 事件监听的版本
- DOM L0版本
事件源.on事件=function(){} - DOM L2版本
事件源.addEventListener(事件,事件处理函数) - 区别:
on方式会被覆盖**,addEventListener方式可绑定多次**,拥有事件更多特性,推荐使用
1.3 事件类型

1.4 事件对象
- 事件对象是什么?
- 也是个对象,这个对象里有事件触发时的相关信息
- 例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息
- 使用场景
- 可以判断用户按下哪个键,比如按下回车键可以发布新闻
- 可以判断鼠标点击了哪个元素,从而做相应的操作
1.4.1 获取事件对象
-
语法:如何获取
- 在事件绑定的回调函数的第一个参数就是事件对象
- 一般命名为event、ev、e
-
举例
元素.addEventListener('click',function(e){ //参数e就是事件对象 })
1.4.2 事件对象常用属性
-
部分常用属性
type- 获取当前的事件类型
clicentX/clientY- 获取光标相对于浏览器可见窗口左上角的位置
offsetX/offsetY- 获取光标相当于当前dom元素左上角的位置
key- 用户按下的键盘的值
- 现状不提倡使用keyCode
-
用法举例
<button> 按钮 </button> <script> const btn = document.querySelector('.btn') //修改元素样式 btn.addEventListener('click',function(event){ //获取用户按下的键盘值 console.log(event.key) //获取当前事件类型 console.log(event.type) }) </script>
1.5 环境对象
环境对象:指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境。
作用:
-
函数调用方式不同,this 指代的对象也不同
-
谁调用,this 就是谁
- 直接调用函数,就是相当于
windows.函数,此时this指向的是window - 如果是按钮调用的函数,this指向的就是这个按钮对象
- 直接调用函数,就是相当于
-
举例
function(){ console.log(this)//指向的是window } const btn=document.querySelector('button') btn.addEventListener('click',function(){ console.log(this)//返回的是btn对象 })
二,事件流
2.1 事件流与两个阶段说明
事件流:指的是事件完整执行过程中的流动路径。

说明:假设页面里有个 div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段
简单来说:捕获阶段是 从父到子, 冒泡阶段是从子到父
实际工作都是使用事件冒泡为主
2.2 事件捕获
事件捕获概念:
-
从 DOM 的根元素开始去执行对应的事件 (从外到里)
-
代码:
DOM元素.addEventListener(事件类型,事件处理函数,是否使用捕获机制)- addEventListener第三个参数传入true代表的是捕获阶段触发(很少使用)
- 如果传入false代表冒泡阶段触发,默认是false
-
代码举例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="./css/bootstrap.min.css" /> <title>Document</title> <style> .father { width: 100px; height: 100px; background-color: red; } .son { width: 50px; height: 50px; background-color: blue; } </style> </head> <body> <div class="father"> <div class="son"></div> </div> <script> const father = document.querySelector(".father"); const son = document.querySelector(".son"); document.addEventListener( "click", function (e) { alert("doc clicked"); }, true ); father.addEventListener( "click", function (e) { alert("father clicked"); }, true ); son.addEventListener( "click", function (e) { alert("son clicked"); }, true ); </script> </body> </html>
2.3 事件冒泡
事件冒泡:当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的 同名事件
事件冒泡是默认存在的
L2 事件监听第三个参数是 false,或者默认都是冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./css/bootstrap.min.css" />
<title>Document</title>
<style>
.father {
width: 100px;
height: 100px;
background-color: red;
}
.son {
width: 50px;
height: 50px;
background-color: blue;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
const father = document.querySelector(".father");
const son = document.querySelector(".son");
document.addEventListener("click", function (e) {
alert("doc clicked");
});
father.addEventListener("click", function (e) {
alert("father clicked");
});
son.addEventListener("click", function (e) {
alert("son clicked");
});
</script>
</body>
</html>
2.4 阻止冒泡
-
问题:因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素
-
需求:若想把事件就限制在当前元素内,就需要阻止事件冒泡
-
前提:阻止事件冒泡需要拿到事件对象
-
语法:
事件对象.stopPropagation() -
举例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="./css/bootstrap.min.css" /> <title>Document</title> <style> .father { width: 100px; height: 100px; background-color: red; } .son { width: 50px; height: 50px; background-color: blue; } </style> </head> <body> <div class="father"> <div class="son"></div> </div> <script> const father = document.querySelector(".father"); const son = document.querySelector(".son"); document.addEventListener("click", function (e) { alert("doc clicked"); }); father.addEventListener("click", function (e) { alert("father clicked"); }); son.addEventListener("click", function (e) { alert("son clicked"); //阻止流动 e.stopPropagation(); }); </script> </body> </html> -
注意:此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效
2.5 解绑事件
-
on 事件方式,直接使用 null 覆盖偶就可以实现事件的解绑
btn.onclick = function(){ alert('点击') } //解绑事件 btn.onclick=null -
addEventListener 方式,必须使用,
removeEventListener(事件类型,事件处理函数,[获取捕获或者冒泡阶段])function fn(){ alert('点击') } //绑定事件 btn.addEventListener('click',fn) //解绑事件 btn.removeEventListener('click',fn)- 注意:匿名函数无法解绑
2.6 鼠标经过事件的区别
鼠标经过事件:
mouseover和mouseout会有冒泡效果mouseenter和mouseleave没有冒泡效果(推荐)
2.7 两种注册事件的区别
- 传统on注册(L0)
- 同一个对象,后面注册的事件会覆盖前面注册(同一个事件)
- 直接使用null覆盖偶就可以实现事件的解绑
- 都是冒泡阶段执行的
- 事件监听注册(L2)
- 语法:
addEventListener(事件类型,事件处理函数,是否使用捕获) - 后面注册的事件不会覆盖前面注册的事件(同一个事件)
- 可以通过第三个参数去确定是在冒泡或者捕获阶段执行
- 必须使用
removeEventListener(事件类型,事件处理函数,获取捕获或者冒泡阶段) - 匿名函数无法被解绑
- 语法:
三,事件委托
事件委托是利用事件流的特征解决一些开发需求的知识技巧
- 优点:减少注册次数,可以提高程序性能
- 原理:事件委托其实是利用事件冒泡的特点。
- 给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件。
- 实现:
事件对象.target.tagName可以获得真正触发事件的元素
代码举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./css/bootstrap.min.css" />
<title>Document</title>
</head>
<body>
<ul>
<li>第1个li</li>
<li>第2个li</li>
<li>第3个li</li>
<li>第4个li</li>
<li>第5个li</li>
<p>第6个p</p>
</ul>
<script>
const ul = document.querySelector("ul");
ul.addEventListener("click", function (e) {
if (e.target.tagName === "LI") {
//只有li标签才会触发事件
e.target.style.color = "red";
}
});
</script>
</body>
</html>
四,阻止标签默认行为
我们某些情况下需要阻止默认行为的发生,比如 阻止 链接的跳转,表单域跳转
-
语法:
事件对象.preventDefault(); -
代码举例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="./css/bootstrap.min.css" /> <title>Document</title> </head> <body> <form action="https://www.baidu.com"> <input type="submit" value="提交" /> </form> <script> const form = document.querySelector("form"); form.addEventListener("click", function (event) { //阻止表单默认提交行为 event.preventDefault(); alert("提交成功"); }); </script> </body> </html>
五,其他事件
5.1 页面加载事件
-
加载外部资源 (如图片、外联 CSS 和 JavaScript 等) 加载完毕时触发的事件。
-
为什么要学?
- 有些时候需要等页面资源全部处理完了做一些事情
- 老代码喜欢把 script 写在 head 中,这时候直接找 dom 元素找不到
-
事件名:
load -
监听页面所有资源加载完毕:
- 给window添加load事件(window>document)
-
代码举例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="./css/bootstrap.min.css" /> <title>Document</title> <script> //等待页面所有资源加载完毕,就回去指向回调函数 window.addEventListener("load", function () { //获取元素 var btn = document.querySelector("button"); //绑定点击事件 btn.addEventListener("click", function () { alert("按钮被点击了"); }); }); img.addEventListener('load',function(){ //等待图片加载完毕再执行里面的代码 }); </script> </head> <body> <button>按钮</button> </body> </html> -
注:不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定 load 事件
当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像等完全加载
-
事件名:
DOMContentLoaded -
监听页面 DOM 加载完毕
- 给document添加
DOMContentLoaded事件
- 给document添加
-
代码举例
document.addEventListener('DOMContentLoaded',function(){ //执行内容 })
5.2 元素滚动事件
滚动条在滚动的时候持续触发的事件
作用:
-
很多网页需要检测用户把页面滚动到某个区域后做一些处理,比如固定导航栏,比如返回顶部
-
事件名:
scroll -
监听整个页面滚动:
//页面滚动事件 window.addEventListener('scroll',function(){ //执行的操作 })- 给window或者document添加scroll事件
页面滚动事件 -》获取位置
-
scrollLeft和scrollTop属性scrollTop:页面往下滚动,元素超出的部分就是scrollTopscrollLeft:页面往左边滚动,元素超出的部分就是scrollLeft- 单位是px

-
代码举例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="./css/bootstrap.min.css" /> <title>Document</title> </head> <style> div { margin: 400px auto; width: 100px; height: 200px; overflow: scroll; border: 1px solid black; } </style> <body> <div> 我里面有很多内容11111111111111111111111111 我里面有很多内容11111111111111111111111111 我里面有很多内容11111111111111111111111111 我里面有很多内容11111111111111111111111111 我里面有很多内容11111111111111111111111111 我里面有很多内容11111111111111111111111111 我里面有很多内容11111111111111111111111111 我里面有很多内容11111111111111111111111111 我里面有很多内容11111111111111111111111111 我里面有很多内容11111111111111111111111111 </div> <script> const div = document.querySelector("div"); div.addEventListener("scroll", function () { console.log("scrollTop:" + div.scrollTop); console.log("scrollLeft:" + div.scrollLeft); }); </script> </body> </html> -
获取页面滚动多少 px,被卷去多少 px
document.documentElement.scrollTop//获取的是htm标签 -
这俩个值是可读写的
我们可以给页面赋值,让页面打开显示在指定位置
document.documentElement.scrollTop=800//让页面向下拉800px
5.3 页面尺寸事件
-
会在窗口尺寸改变的时候触发事件:
resize
window.addEventListener('resize',function(){ //执行的code }) -
检测屏幕官渡
window.addEventListener('resize',function(){ let width=document.documentElement.clientWidth console.log(width) })
页面尺寸事件 -》获取元素宽高
-
获取元素的可见部分宽高,不包含 border,margin,滚动条
-
clientWidth和clientHeight

-
代码举例
<script> const div = document.querySelector("div"); div.addEventListener("scroll", function () { div.clientHeight; // 内容的高度 div.scrollHeight; // 内容的总高度 }); </script>
六,元素尺寸与位置
-
使用场景
- 前面案例滚动多少距离,都是我们自己算的,最好是页面滚动到某个元素,就可以做某些事。
- 简单说,就是通过js的方式,得到元素在页面中的位置
- 这样我们可以做,页面滚动到这个位置,就可以做某些操作,省去计算了
-
获取宽高
- 获取元素自身的宽高,包括元素自身设置的宽高,padding,border
offsetWidth和offsetHeight- 获取出来的是数值,方便计算
- 注意:获取的是可视宽高,如果盒子是隐藏的,获取的结果是0
-
获取位置
- 获取元素距离自己定位父级元素的左、上距离
offsetLeft和offsetTop注意是只读属性
-
代码举例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="./css/bootstrap.min.css" /> <title>Document</title> </head> <style> div { width: 200px; height: 200px; background-color: pink; margin: 100px; } p { width: 100px; height: 100px; background-color: purple; margin: 50px; } </style> <body> <div> <p></p> </div> <script> const div = document.querySelector("div"); const p = document.querySelector("p"); console.log(div.offsetLeft); console.log(p.offsetTop); console.log(div.offsetWidth); console.log(div.offsetHeight); </script> </body> </html>
-
元素尺寸于位置 -》尺寸
- 获取位置:
元素对象.getBoundingClientRect()
方法返回元素的大小以及相对于视口的位置
- 获取位置:

七,M端事件
移动端也有自己独特的地方。比如触屏事件 touch(也称触摸事件),Android 和 I0S 都有。
-
触屏事件 touch(也称触摸事件),Android 和 IOS 都有。
-
touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指 (或触控笔),对屏幕或者触控板操作。
-
常见的触屏事件如下:
触屏touch事件 说明 touchstart手指触摸到一个 DOM 元素时触发 touchmove手指在一个 DOM 元素上滑动时触发 touchend手指从一个 DOM 元素上移开时触发