注册事件

「1.1注册事件概述」

给元素添加事件,称为注册事件或者绑定事件

注册事件有两种方式,传统方式方法监听注册方式

传统注册方式

  • <button onclick="alert('hi')"></button>
  • btn.onclick = function() { }

特点:

  1. 注册事件的唯一性
  2. 同一元素同一事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数

方法监听注册方式

  • addEventListener()
  • attachEvent() //IE9之前

特点:

  1. W3C标准推荐方式
  2. 同一元素同一事件可以注册多个监听器
  3. 按注册顺序依次执行

「1.2 addEventListener 事件监听方式」

1
eventTarget.addEventListener(type, listener, useCapture)

eventTarget.addEventListener() 方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定事件时,就会执行事件处理函数

该方法接收三个参数:

  • type:事件类型字符串,比如click,mouseover,注意这里不要带on
  • listener:事件处理函数,事件发生时,会调用该监听函数
  • useCapture:可选参数,是一个布尔值,默认false,DOM事件流会详细介绍
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<button>测试按钮0</button>
<button>测试按钮1</button>
<script>
var btns = document.querySelectorAll('button');
// 1.传统方式注册事件,后面会覆盖前面
btns[0].onclick = function() {
alert('hi');
}
btns[0].onclick = function() {
alert('how are you');
}
// 2.事件侦听注册事件 addEventLisener
// (1) 里面事件类型是字符串,必须加引号,并且不带on
// (2) 同一个元素,同一个事件,可以添加多个侦听器(事件处理程序)
btns[1].addEventListener('click', function() {
alert('监听注册事件');
})
btns[1].addEventListener('click', function() {
alert('监听注册依次执行');
})
</script>

「1.3 attachEvent事件监听方式」(不重要)

1
eventTarget.attachEvent(eventNameWithon, callback)

eventTarget.attachEvent()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,指定的回调函数就会被执行。

该方法接收两个参数:

  • eventNameWithOn: 事件类型字符串,比如onclick,onmouseover, 这里要带on
  • callback: 事件处理函数,当目标触发事件时回调函数被调用

「1.4 注册事件兼容性解决方案」

兼容性处理原则:首先照顾大多数浏览器,在处理特殊浏览器

删除事件

「2.1删除事件的方法」

1.传统注册方式

eventTarget.onclick = null

2.方法监听注册方式

  • eventTarget.removeEventListener(type, listener, uesCapture);
  • eventTarget.detaEvent(eventNameWithOn, callback);

「2.2删除事件兼容性解决方案」

DOM事件流

我们想水里面扔一块石头,首先它会有一个下降的过程,这个过程就可以理解为从最顶层向事件发生的最具体元素(目标点)的捕获过程;之后会产生泡泡,会在最低点(最具体的元素)之后漂浮到水面上,这个过程相当于事件冒泡。

image-20220716161228567

官方描述

事件流描述的时页面中接收事件的顺序

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流

比如我们给div注册了一个点击事件,DOM的事件流就分三个阶段:

  1. 捕获阶段
  2. 当前目标阶段
  3. 冒泡阶段就

image-20220716161708853

注意:

  1. 事件发生时,会在元素节点之间按照特定的顺序传播,这个传播过程即DOM 事件流
  2. js代码中只能执行捕获或者冒泡其中的一个阶段
  3. onclick和attachEvent 只能得到冒泡阶段
  4. addEventListener(type, listener, useCapture)第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(默认false),表示在事件冒泡阶段调用事件处理程序
  5. 实际开发很少用事件捕获,我们更关注事件冒泡
  6. 有些事件是没有冒泡的,比如onblur,onfocus ,onmouseleave
  7. 事件冒泡有时候会带来麻烦,下文提到

事件对象

「什么是事件对象」

1
2
3
eventTarget.onclick = function(event) {}
eventTarget.addEventListener('click', function(event) {})
// 这个event就是事件对象,我们还喜欢写成e或则evt

官方解释:event对象代表事件的状态,比如键盘按键的状态,鼠标按钮的状态

简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象event,它有很多种属性和方法,比如:

  1. 谁绑定这个事件
  2. 鼠标触发事件的话,会得到鼠标的相关信息,比如鼠标位置
  3. 键盘触发事件的话,会得到键盘的相关信息,如按了哪个键
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div>传统</div>
<span>侦听</span>
<script>
// 事件对象
var div = document.querySelector('div');
div.onclick = function(event) {
console.log(event);
}
var span = document.querySelector('span');
span.addEventListener('click', function(e) {
console.log(e);
})
// 1.event是一个事件事件对象,写到我们侦听函数的小括号里面,当作形参来看
// 2.事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
// 3.事件对象 是 我们事件的一系列相关数据的集合,跟事件相关的,比如鼠标点击里面就包含了鼠标的相关信息
// 4.这个事件我们可以自己命名,比如event,evt,e
// 5.事件对象也有兼容性问题 ie678通过windows.event
</script>

event是一个形参,系统帮我们设定为事件对象,不需要传递实参过去

当我们注册事件时,event对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)

兼容性方案:e = e || window.event

「事件对象的常见属性和方法」

事件对象属性方法 说明
e.target 返回触发事件的对象(标准)
e.srcElement 返回出发事件的对象(非标准 ie678)
e.type 返回事件的类型 比如click mouseover 不带on
e.cancelBubble 该属性阻止事件冒泡 (非标准 ie678)
e.returnValue 该属性阻止默认事件(默认行为),比如不让链接跳转(非标准 )
e.preventDefault() 该方法阻止默认事件(默认行为),比如不让链接跳转(标准)
e.stopPropagation() 阻止冒泡(标准)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div>123</div>
<ul>
<li>abc</li>
<li>abc</li>
</ul>
<script>
// 1,e.terget 返回的是触发事件的对象(元素) ,this返回的是绑定事件的对象(元素)
// 区别:e.target点击了那个元素,就返回那个元素;this 那个元素绑定了这个点击事件,那么就返回谁
var div = document.querySelector('div');
div.addEventListener('click', function(e) {
console.log(e.target);
console.log(this);
})
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
//我们给ul绑定了事件,则this就指向ul
console.log(this);
//e.target指向我们点击的对象,谁触发了这个事件;我们点击的是li e.target指向就是li
console.log(e.target);
})
</script>
1
2
3
4
5
6
7
8
9
10
11
<div>123</div>
<script>
// 1.返回事件类型
var div = document.querySelector('div');
div.addEventListener('click', fn);
div.addEventListener('mouseover', fn);
div.addEventListener('mouseout', fn);
function fn(e) {
console.log(e.type);
}
</script>
1
2
3
4
5
6
7
8
<a href="http://www.baidu.com">百度</a>
<script>
//阻止默认行为(事件)
var a = document.querySelector('a');
a.addEventListener('click', function(e) {
e.preventDefault(); // dom标准写法
})
</script>

「阻止事件冒泡」

事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到DOM最顶节点

1
2
3
4
5
6
7
8
9
10
11
<div class="father">
<div class="son">son</div>
</div>
<script>
// 阻止冒泡 dom推荐标准 stopPropagation()
var son = document.querySelector('.son');
son.addEventListener('click', function(e) {
alert('son');
e.stopPropagation(); //标准 propagation传播
e.cancelBubble = true; //非标准 cancel取消 bubble泡泡
},false);

事件委托

事件冒泡本身的特性,会带来坏处,也会带来好处,需要灵活掌握

班级有100学生,快递员有100快递,如果一个一个送花费时间长,同时每个学生领取花费时间同样长

解决方案:快递员把100快递委托给班主任,班主任发放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<ul>
<li>知否知否,点我应有弹窗在手</li>
<li>知否知否,点我应有弹窗在手</li>
<li>知否知否,点我应有弹窗在手</li>
<li>知否知否,点我应有弹窗在手</li>
<li>知否知否,点我应有弹窗在手</li>
</ul>
<script>
//事件委托核心原理:给父节点添加侦听器,利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
// alert('知否知否');
// e.target 可以得到我们点击的对象
e.target.style.backgroundColor = 'pink';
})
</script>

常用鼠标事件

「常用鼠标事件」

鼠标事件 触发条件
onclick 鼠标点击左键触发
onmouseover 鼠标经过触发
onmouseout 鼠标离开触发
onfocus 获得鼠标焦点触发
onblur 失去鼠标焦点触发
onmousemove 鼠标移动触发
onmouseup 鼠标弹起触发
onmousedown 鼠标按下触发

1.禁止鼠标右键菜单

contexmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认上下文菜单

1
2
3
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})

2.禁止鼠标选中

1
2
3
document.addEventListener('selectstart', function(e) {
e.preventDefault();
})

「鼠标事件对象」

1
2
3
4
5
6
7
8
9
10
11
12
13
document.addEventListener('click', function(e) {
//1.client鼠标在可视区的x和y坐标
console.log(e.clientX);
console.log(e.clientY);
console.log('-----------------');
//2.page鼠标在页面文档的x和y坐标
console.log(e.pageX);
console.log(e.pageY);
console.log('-----------------');
//3.screen鼠标在电脑屏幕的x和y坐标
console.log(e.screenX);
console.log(e.screenY);
})

案例:跟随鼠标的天使

1

常用键盘事件

「常用键盘事件」

键盘事件 触发条件
onkeyup 某个键盘按键被松开时触发
onkeydown 某个键盘按键被按下时触发
onkeypress 某个键盘按键被按下时触发 但它不识别功能键比如ctrl shift
  • 如使用addEventListener 不需要on
  • 三个事件执行顺序; keydown–keypress–keyup

「键盘事件对象」

键盘事件对象属性 说明
keyCode 返回改键的ASCII值
  • keypress不识别功能键,但keyCode属性能区分大小写,返回不同的ASCII值