首页 > 技术文章 > JavaScript 【事件】事件对象

xiaoxuStudy 2020-06-16 15:35 原文

以下大部分为学习《JavaScript 高级程序设计》(第 3 版) 所做笔记。

目录:

1. DOM中的事件对象

2. IE中的事件对象

3. 跨浏览器的事件对象

 

Q :  触发DOM上某个事件时产生一个事件对象event,这个对象中包含什么?

A :  包含导致事件的元素、事件的类型以及其他事件相关的信息。包含与创建它的特定事件有关的属性和方法。

Q :  所有浏览器都支持 event 对象吗?

A :都支持。但是支持方式不同。

Q :  event 对象什么时候存在?

A :  只有在事件处理程序执行期间,event 对象才会存在。

Q :  event 事件什么时候会被销毁?

A :一旦事件处理程序执行完成, event 对象就会被销毁。

 

DOM中的事件对象

兼容 DOM 的浏览器会将一个 event 对象传入到事件处理程序中,无论指定事件处理程序时使用什么方法(DOM0级或者DOM2级),都会传入 event 对象。

点击按钮,控制台输出:

  event 的属性与方法 

触发 click 事件时产生事件 event ,在控制台输出 event 查看属性和方法:

  属性 currentTarget、target  

event 对象的 currentTarget 属性表示事件处理程序正在处理事件的那个元素,target 属性表示事件的目标。

在对象处理程序内部,对象 this 始终等于 currentTarget 的值,但是对象 this 并不始终等于 target 的值。

对象 this 并不始终等于 target 的值,举个例子:

点击按钮,控制台输出:

因为事件处理程序注册在 document.body 上,所以 this 跟 currentTarget 都等于 document.body

因为 click 事件真正的元素是按钮元素,所以 target 元素等于按钮元素

  属性 type  

Q : 什么时候可以使用 type 属性?

A : 需要通过一个函数处理多个事件时

下面举个例子。onclick、onmouseover、onmouseout 事件处理程序注册在按钮上,handler 函数处理多个事件。触发事件时产生一个事件对象 event,通过检测 event 对象的 type 属性让 handler 函数确定发生了什么并且执行相应的操作。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
	</head>
	<body>
		<input type="button" id="btn1" value="btn"/>
		<script>
			var btn = document.getElementById("btn1");
			var handler = function(event){
				switch(event.type){
					case "click":
						console.log("按钮被点击");
						break;
					case "mouseover":
						event.target.style.backgroundColor = "red";
						break;
					case "mouseout":
						event.target.style.backgroundColor = "";
						break;
				}
			};
			btn.onclick = handler;
			btn.onmouseover = handler;
			btn.onmouseout = handler;
		</script>
	</body>
</html>

  preventDefault()方法   

preventDefault() 方法能够阻止特定事件的默认行为。前提:cancelable 属性为 true。

举个栗子:链接的默认行为就是被单击时会导航到其 href 特性指定的 URL。可以通过链接的 onclick 事件处理程序取消它。

  stopPropagation()方法  

stopPropagation() 用于立即停止事件在 DOM 层次中的传播。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
	</head>
	<body>
		<input type="button" id="btn1" value="按钮"/>
		<script>
			var btn = document.getElementById("btn1");
			btn.onclick = function(event){
				console.log("btn");		
				event.stopPropagation();
			};
			document.body.onclick = function(event){
				console.log("document.body");	
			};
		</script>
	</body>
</html>

点击按钮之后,控制台输出:

说明:

点击了按钮,触发了在按钮上注册的事件处理程序,事件处理程序处于目标对象上。如果没有使用 stopPropagation,接下来执行的事件处理程序是冒泡阶段触发的添加到 document.body 中的点击事件。但是使用了 stopPropagation() 函数中止了事件在 DOM 层次上传播,所以没有触发添加到 document.body 上的事件处理程序。

如果没有语句“ event.stopPropagation(); ”,点击按钮之后,控制台会输出:

   属性 eventPhase  

Q :  eventPhase 有啥用?

A :可以用来确定事件当前正位于事件流的哪个阶段。

Q :怎么确定事件当前正位于事件流的哪个阶段?

A :▶eventPhase 为 1 ,在捕获阶段调用事件处理程序

  ▶eventPhase 为 2 ,事件处理程序处于目标对象上

  ▶eventPhase 为 3 ,在冒泡阶段调用事件处理程序

下面举个例子:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
	</head>
	<body>
		<input type="button" id="btn1" value="按钮"/>
		<script>
			var btn = document.getElementById("btn1");
			btn.onclick = function(event){
				console.log("结果1:", event.eventPhase);		//输出:2
			};
			document.body.addEventListener("click", function(event){
				console.log("结果2:", event.eventPhase);		//输出:1
			}, true);
			document.body.onclick = function(event){
				console.log("结果3:", event.eventPhase);		//输出:3
			}
		</script>
	</body>
</html>

点击按钮,控制台输出:

说明:

  点击按钮时,首先执行的事件处理程序是捕获阶段触发的添加到 document.body 中的那一个。然后,触发在按钮上注册的事件处理程序。最后,执行的事件处理程序是冒泡阶段触发的添加到 document.body 中的那一个。

(DOM事件流图)

 

IE中的事件对象

 ▶ 访问 IE 中的 event 有几种方式,取决于指定事件处理程序的方法。

 ▶ 使用 DOM0 级方法添加事件处理程序时,event 对象作为 window对象的一个属性存在。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
	</head>
	<body>
		<input type="button" id="btn1" value="按钮"/>
		<script>
			var btn = document.getElementById("btn1");
			btn.onclick = function(){
				var event = window.event;	//event 对象作为 window 对象的一个属性存在
				console.log(event.type);
			}
		</script>
	</body>
</html>

 

通过 HTML 特性指定事件处理程序也可以通过一个名为 event 的变量来访问 event:

点击按钮,控制台输出 event 的属性和方法,下面截取了部分进行说明:

 

不能认为 this 会始终等于事件目标,因为事件处理程序的作用域是根据指定它的方式来确定的,为了保险最好使用 event.srcElement。

 

 属性 returnValue 

returnValue 属性相当于 DOM 中的 preventDefault() 方法,作用都是取消给定事件的默认行为。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
	</head>
	<body>
		<a id="link1" href="http://www.baidu.com">点击跳转百度</a>
		<script>
			var link = document.getElementById("link1");
			link.onclick = function(){
				window.event.returnValue = false;
			};
		</script>
	</body>
</html>

 

说明:

如果没有设置 returnValue 属性值为 false,点击 “点击跳转百度” 页面会跳转到百度,但是设置了returnValue 属性值为 false 后链接的默认行为被停止了,页面不跳转。

 

  属性 cancelBubble 

cancelBubble 属性相当于 DOM 中的 stopPropagation() 方法,作用都是停止事件冒泡。

☆ cancelBubble 只能取消事件冒泡(因为IE不支持事件冒泡)

stopPropagation() 能取消事件捕获与冒泡

举个栗子,不设置 cancelBubble 为 true 时,点击按钮先执行注册在按钮上的点击事件,然后执行在冒泡阶段触发的添加到 document.body 上的点击事件。设置了cancelBubble 为 true 后, 停止了事件冒泡,不执行在冒泡阶段触发的添加到 document.body 上的点击事件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
	</head>
	<body>
		<input type="button" id="btn1" value="按钮"/>
		<script>
			var btn = document.getElementById("btn1");
			btn.onclick = function(){
				console.log("按钮被点击了");
				//设置 cancalBubble 为 true,阻止事件冒泡
				window.event.cancelBubble = true;	
			};
			document.body.onclick = function(){
				console.log("body被点击了");
			}
		</script>
	</body>
</html>

点击按钮,控制台输出:

 

DOM 与 IE 的 event 对象的异同小结  

推荐阅读