本章字数7873字。
上一篇文章《JavaScript进阶认识:什么是事件冒泡过程与捕获过程?有什么用处?》我们讲到事件对象e,利用了一个方法e.target,通过冒泡过程,从而实现了点击父级元素里面的子元素触发父级元素事件,再从父级元素事件对象e,找到真正触发事件发生的子元素源,实现隔行换色的代码。这个技巧要认真琢磨。
那么,什么是事件对象e呢?
事件对象e,是event的简称。当一个事件被触发时候,这个事件的有关数据都会被存储在一个事件对象e里面,这个对象e有许多固定方法提供给我们查看里面各种数据。
我们打个比方去理解这个事件e,比如飞机失事,飞机相当于是事件源,失事是事件类型,那么当这个事件源【飞机】触发了事件类型【失事】时,人们就会通过查询飞机黑匣子里面的相关数据去了解整个事件发生的经过,而这个黑匣子就是事件对象e。
了解了什么是事件对象后,我们来学习事件对象常用的方法:
事件对象方法 | 解释 |
---|---|
e.eventPhase | 查看事件触发时所处的阶段 |
e.target | 用于获取触发事件的元素(e.srcElement 用于获取触发事件的元素,低版本浏览器使用) |
e.currentTarget | 用于获取绑定事件的事件源元素 |
e.type | 获取事件类型 |
e.clietX / e.clientY | 所有浏览器都支持,鼠标距离浏览器窗口左上角的距离 |
我们一个个来解释
1.测试e.eventPhase
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<style>
#box1{
width: 300px;
height: 300px;
background-color: yellowgreen;
}
#box2{
width: 200px;
height: 200px;
background-color: pink;
}
#box3{
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
<script>
// 获取元素
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
// 添加事件
box1.onclick = function (e) {
// e指的就是存储事件对象的参数,只要事件被触发(即box1被点击),e就会自动接收数据
e = e || window.event; // 解决兼容问题
// e.eventPhase 判断出事件执行时处于哪个阶段
// 1:捕获阶段
// 2:目标阶段(指的是事件真正执行的阶段)
// 3:冒泡阶段
console.log(e.eventPhase);
};
</script>
</body>
</html>
效果如下:
解释:我们需要知道控制台显示3和2的所代表信息,在验证事件所处阶段中,1表示捕获过程,2表示事件执行过程,3表示冒泡过程。事件阶段只有三种情况:一是冒泡过程,二是捕获过程,三是既没有冒泡过程也没有捕获过程(第三种情况先不用管),这跟非黑即白成语含义是一样的,要么捕获要么冒泡。
因此,点击box3显示的3代表冒泡阶段,点击box2显示的3也代表冒泡阶段,点击box1显示的2代表事件执行阶段,也就是说box1是真正的事件发生地,但到底是谁触发box1事件发生的,要看我们点击是box3、box2、还是box1。
冒泡阶段指的是从哪里使得事件发生的方向【是从父到子方向(捕获),还是从子到父方向(冒泡)】。其中,这个事件指的是box1.onclick。
2.测试e.target
前面,我们知道事件对象e有版本问题,因此我们这样写兼容代码:
e = e || window.event;
e.target也有兼容问题,e.srcElement 用于获取触发事件的元素,低版本浏览器使用,因此我们也这样写代码
var target = e.target | e.srcElement ;
测试e.target代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<style>
#box1{
width: 300px;
height: 300px;
background-color: yellowgreen;
}
#box2{
width: 200px;
height: 200px;
background-color: pink;
}
#box3{
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
<script>
// 获取元素
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
// 添加事件
box1.onclick = function (e) {
// e指的就是存储事件对象的参数,只要事件被触发(即box1被点击),e就会自动接收数据
e = e || window.event; // 解决兼容问题
// e.eventPhase 判断出事件执行时处于哪个阶段
// 1:捕获阶段
// 2:目标阶段(指的是真正执行的阶段)
// 3:冒泡阶段
console.log(e.eventPhase);
// 获取真正触发事件的元素
var target = e.target || e.srcElement;
console.log(target);
};
</script>
</body>
</html>
解释:从图片我们知道,点击box3则box3元素是触发事件的元素,点击box2则box2是触发事件元素,点击box1是触发事件的源元素。这个事件指的是box1.onclick 。
3.测试e.currentTarget
获取绑定事件的事件源
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<style>
#box1{
width: 300px;
height: 300px;
background-color: yellowgreen;
}
#box2{
width: 200px;
height: 200px;
background-color: pink;
}
#box3{
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
<script>
// 获取元素
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
// 添加事件
box1.onclick = function (e) {
// e指的就是存储事件对象的参数,只要事件被触发,e就会自动接收数据
// 兼容问题
e = e || window.event;
// e.eventPhase 判断出事件执行时处于哪个阶段
// 1:捕获阶段
// 2:目标阶段(指的是真正执行的阶段)
// 3:冒泡阶段
console.log(e.eventPhase);
// 获取绑定事件(注册事件)的事件源元素
console.log(e.currentTarget);
};
</script>
</body>
</html>
显示效果如下:
解释:从图片我们可以知道,点击任一元素都指向了真正触发事件的源元素box1。
4.测试e.type
e.type测试的事件类型是什么
<!DOCTYPE html>
<html lang="en">
<head>
<title>测试</title>
<style>
#box1{
width: 200px;
height: 200px;
background-color: yellowgreen;
}
</style>
</head>
<body>
<div id="box1"></div>
<script>
// 获取元素
var box1 = document.getElementById("box1");
// e.type 属性获取事件类型
box1.onclick = function (e) {
// 事件对象兼容
e = e || window.event;
// 触发的事件类型
console.log(e.type);
};
</script>
</body>
</html>
效果如下;
控制台显示的click鼠标点击事件。
当然,e.type用处不仅仅局限与此。如果要编写一个鼠标移入和移出事件,很多同学会想到下面这种方法:
<!DOCTYPE html>
<html lang="en">
<head>
<title>测试</title>
<style>
#box1{
width: 200px;
height: 200px;
background-color: yellowgreen;
}
</style>
</head>
<body>
<div id="box1"></div>
<script>
// 获取元素
var box1 = document.getElementById("box1");
// 更多时候可能给同一个元素对象添加不同的事件类型,对应执行的事件函数内部的代码 不同
box1.onmouseover = function () {
box1.style.backgroundColor = "skyblue";
};
box1.onmouseout = function () {
box1.style.backgroundColor = "yellowgreen";
};
</script>
</body>
</html>
解释:在更多时候,我们会给一个元素对象添加不同事件类型,对应执行事件函数内部的不同代码,但这有一个缺陷,即每创建一个函数就会多占用一个内存,这不利于浏览器的性能优化。
那么如何解决这个【添加多个函数,占用更多的内存】问题呢?答案是将两个函数封装成一个函数。
我们可以将所有给一个元素绑定的事件的事件函数写在一个函数内,通过函数内部的 e.type 判断走不同的分支。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<title>测试</title>
<style>
#box1{
width: 200px;
height: 200px;
background-color: yellowgreen;
}
</style>
</head>
<body>
<div id="box1"></div>
<script>
// 获取元素
var box1 = document.getElementById("box1");
box1.onmouseover = fn;
box1.onmouseout = fn;
// 避免添加多个函数,占用更多的内存
function fn(e) {
e = e || window.event;
// 根据事件类型,执行不同的代码
switch (e.type) {
case "mouseover":
box1.style.backgroundColor = "pink";
break;
case "mouseout":
box1.style.backgroundColor = "yellowgreen";
break;
}
}
</script>
</body>
</html>
解释:只要触发了box1元素的事件,就产生一个e储存了各种信息,通过e.type查看事件的类型匹配不同的执行方法。
5.测试e.clientX
比如要实现一个需求:实现图片跟随鼠标移动而移动。
<!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>
* {
margin: 0;
padding: 0;
}
#pic {
position: fixed;
}
</style>
</head>
<body>
<img src="images/tianshi.gif" alt="" id="pic">
<script>
// 通过 鼠标移动事件给 图片添加 left 和 top 的值
// 1.获取元素
var pic = document.getElementById("pic");
// 2.给整个文档添加鼠标移动事件
document.onmousemove = function (e) {
// 2.1、e的兼容写法
e = e || window.event;
// 2.2、给元素的css 属性赋值
pic.style.left = e.clientX + "px";
pic.style.top = e.clientY + "px";
};
</script>
</body>
</html>
实现效果如下:
解释:通过e.clientX/e.clientY可以轻易获取鼠标距离左上角的位置,从而改变图片在整个文档的位置。
6.this
注册事件,this指向的是触发事件的源元素
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<style>
#box1{
width: 300px;
height: 300px;
background-color: yellowgreen;
}
#box2{
width: 200px;
height: 200px;
background-color: pink;
}
#box3{
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
<script>
// 获取元素
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
// 添加事件
box1.onclick = function (e) {
e = e || window.event;
console.log(e.eventPhase);
// this 指向
console.log(this);
};
</script>
</body>
</html>
this指向box1:
效果如下:
常用的用法就是以上的部分了,更多web事件情况从此链接参考:https://developer.mozilla.org/zh-CN/docs/Web/Events