目录
学习来源: https://www.bilibili.com/video/BV1HJ41147DG
4、事件对象
1)、什么是事件对象
事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象。
比如:
- 谁绑定了这个事件。
- 鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置。
- 键盘触发事件的话,会得到键盘的相关信息,如按了哪个键。
2)、事件对象的使用
事件触发发生时就会产生事件对象,并且系统会以实参的形式传给事件处理函数。
所以,在事件处理函数中声明1个形参用来接收事件对象。
语法
// event 就是事件对象,也可以写成 e 或 evt,写到监听函数的小括号里面,当形参来看
eventTarget.onclick = function (event) {}
eventTarget.addEventListener('click', function(event) {})
eventTarget.addEventListener('click', fn)
function fn(e) {}
注释
- 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
示例
<!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: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div>123</div>
<script>
// 事件对象
var div = document.querySelector('div');
// 1、
div.onclick = function (e) {
console.log(e);
}
// 2、
div.addEventListener('click', function (e) {
console.log(e);
})
// 3、
div.addEventListener('click', fn)
function fn(e) {
console.log(e);
}
</script>
</body>
</html>
3)、事件对象的兼容性处理
事件对象本身的获取存在兼容问题:
- 标准浏览器中是浏览器给方法传递的参数,只需要定义形参 e 就可以获取到。
- 在 IE6~8 中,浏览器不会给方法传递参数,如果需要的话,需要到 window.event 中获取查找。
解决方法
e = e || window.event;
// 只要“||”前面为false, 不管“||”后面是true 还是 false,都返回 “||” 后面的值。
// 只要“||”前面为true, 不管“||”后面是true 还是 false,都返回 “||” 前面的值。
<script>
var div = document.querySelector('div');
div.onclick = function (e) {
// 事件对象
e = e || window.event;
console.log(e);
}
</script>
4)、事件对象的属性和方法
e.target 和 this 的区别
- this 返回的是事件绑定的元素(绑定这个事件处理函数的元素)
- e.target 返回的是触发事件的对象(元素)
通常情况下e.target
和this
是一致的
但有一种情况不同,那就是在事件冒泡时(父子元素有相同事件,单击子元素,父元素的事件处理函数也会被触发执行),这时候this
指向的是父元素,因为它是绑定事件的元素对象;而e.target
指向的是子元素,因为他是触发事件的那个具体元素对象,即e.target
点击了哪个元素,就返回哪个元素,this
哪个元素绑定了这个点击事件,那么就返回谁。
<!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: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div>123</div>
<ul>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<script>
var div = document.querySelector('div');
div.addEventListener('click', function (e) {
console.log(e.target); // <div>123</div>
console.log(this); // <div>123</div>
})
// 了解兼容性
div.onclick = function (e) {
e = e || window.event;
var target = e.target || e.srcElement;
console.log(target); // <div>123</div>
}
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
// 我们给ul 绑定了事件,那么this 就指向 ul
console.log(this); // <ul>...</ul>
// e.currentTarget 与 this 非常相似,IE6~8 不认识
console.log(e.currentTarget); // <ul>...</ul>
// e.target 指向我们点击的那个对象,谁触发了这个事件 我们点击的是 li,则 e.target 指向的就是li
console.log(e.target); // <li>abc</li>
})
</script>
</body>
</html>
返回事件的类型 e.type
<body>
<div>123</div>
<script>
// e.type 返回事件的类型
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>
</body>
阻止默认行为
html中一些标签有默认行为,例如 a 标签被单击后,默认会进行页面跳转
<body>
<a href="http://www.baidu.com">百度</a>
<br><br>
<form action="http://www.baidu.com">
<input type="submit" value="提交" name="sub">
</form>
<script>
// 阻止默认行为(事件) 让链接不跳转 或者让提交按钮不提交
var a = document.querySelector('a');
a.addEventListener('click', function (e) {
e.preventDefault(); // dom 标准写法
})
// 传统的注册方式
a.onclick = function (e) {
// 普通浏览器 e.preventDefault(); 方法
e.preventDefault();
// 低版本浏览器 ie678 returnValue 属性
e.returnValue;
// 我们可以利用return false 也能阻止默认行为 没有兼容性问题
// 特点: return 后面的代码不执行了,而且只限于传统的注册方式
return false;
alert(11); // 代码不执行
}
</script>
</body>
阻止事件冒泡
事件冒泡本身的特性,会带来的坏处,也会带来的好处。
- 标准写法:利用事件对象里面的 stopPropagation() 方法
e.stopPropagation();
- 非标准写法:IE6~8 利用事件对象里面的 cancelBubble 属性
e.cancelBubble = true;
示例
<!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>
.father {
overflow: hidden;
width: 300px;
height: 300px;
margin: 100px auto;
background-color: pink;
text-align: center;
}
.son {
width: 200px;
height: 200px;
margin: 50px;
background-color: purple;
line-height: 200px;
color: #fff;
}
</style>
</head>
<body>
<div class="father">
<div class="son">son儿子</div>
</div>
<script>
// 阻止冒泡 dom 推荐的标准 stopPropagation()
var son = document.querySelector('.son');
son.addEventListener('click', function (e) {
// 给son注册单击事件
alert('son');
e.stopPropagation(); // stop 停止 Propagation 传播
e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡
}, false);
var father = document.querySelector('.father');
// 给father注册单击事件
father.addEventListener('click', function () {
alert('father');
}, false);
// 给document注册单击事件
document.addEventListener('click', function () {
alert('document');
}) // 点击son盒子,弹出son;点击father盒子,依次弹出father、document;点击document盒子,弹出document
</script>
</body>
</html>
阻止事件冒泡的兼容性处理
if (e && e.stopPropagation) {
e.stopPropagation();
} else {
window.event.cancelBubble = true;
}