JavaScript|小白学事件流(含各种辅助记忆案例)

本博文源于js基础,今天学习js的事件流。事件流可以让我们对整个h5+c3有个“心中有丘壑”的把握。本博文包含以下内容

事件流

js有规定,两个div嵌套,内层div放置一个按钮,点击这个按钮之后,不仅触发了这个按钮的点击事件,而且也触发了两个div的点击事件,甚至也触发了body和window的点击事件。
其中,最外层的元素和最内层的元素谁先触发事件。js规定了一个事件的传播方向,称为事件流。 事件流依次有两个阶段:事件捕获阶段、事件冒泡阶段。

冒泡阶段和捕获阶段

  • 事件捕获阶段:从外层元素往内层传播。
  • 事件冒泡阶段:从内层元素往外层传播。
例子:测试事件流响应
案例效果

从上往下按钮的事件依次被执行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

附上代码
<body>
	<div id="box1">
		<div id="box2">
			<button id="btn">按我</button>
		</div>
	</div>
	<script type="text/javascript">
		var box1 = document.getElementById("box1");
		var box2 = document.getElementById("box2");
		var btn = document.getElementById("btn");
		
		btn.onclick = function() {
			alert("按钮被点击");
		}
		box1.onclick = function() {
			alert("box1被点击");
		}
		
		box2.onclick = function() {
			alert("box2被点击");
		}
	</script>
</body>

DOM0级事件监听

何谓0级事件监听,其实它就是一种标准。我们日常用oDiv.onclick = function()添加事件监听,它就是一种DOM0级事件监听。
事件处理函数执行顺序是从最内层依次到最外层的。事件按这个方向传播:按照上面的例子,先是最内层的按钮,然后是box2,接下来是box1、body、document和window对象。事件处理函数的书写顺序和触发的先后没有任何关系。
DOM0级事件的局限性是它只能从内到外监听到事件的冒泡阶段,无法监听捕获阶段的点击事件还有一个特点是支持覆盖。
例如:

box1.onclick = function() {alert("我弹不出来");};
box1.onclick = function() {alert("弹出我,我把上面的覆盖了");};
//最后执行第二条语句

DOM2级事件监听

在DOM2标准中,新增加了addEventListener()函数,称为DOM2级事件监听。它可以灵活地设置监听的阶段。
函数中有3个参数,格式如下:

  • 第1个参数是事件名,这里的事件名不能写on前缀
  • 第2个参数是事件处理函数,即事件发生时做的事情
  • 第3个参数时布尔值,true表示监听捕获阶段,false表示监听冒泡阶段

DOM2级的事件监听中,如果给同一个元素的同一个事件名的同一个阶段添加多个事件监听,彼此不覆盖,谁先写就先执行谁。

例子:监听按钮被点击的捕获和冒泡阶段
实验效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
简而言之:从外向内捕获,从内向外冒泡。
对于最内层按钮来说,谁先写就先执行谁,不分捕获和冒泡。

附上代码
<body>
	<div id="box1">
		<div id="box2">
			<button id="btn">按我</button>
		</div>
	</div>
	<script type="text/javascript">
		var box1 = document.getElementById("box1");
		var box2 = document.getElementById("box2");
		var btn = document.getElementById("btn");
		
		box1.addEventListener("click",function() {
			alert("我是box1的捕获阶段");
		},true);
		
		box1.addEventListener("click",function() {
			alert("我是box1的冒泡阶段");
		},false);
		
		box2.addEventListener("click",function() {
			alert("我是box2的捕获阶段");
		},true);
		
		box2.addEventListener("click",function() {
			alert("我是box2的冒泡阶段");
		},false);
		btn.addEventListener("click",function() {
			alert("我是btn的捕获阶段");
		},true);
		
		btn.addEventListener("click",function() {
			alert("我是btn的冒泡阶段");
		},false);
	</script>
</body>

事件监听的移除

有时需要移除元素的事件监听,例如拖拽效果。
0级事件监听的移除很简单,直接把onclick属性设置为null即可:

oBox.onclick = null;

此时oBox对象就没有onclick事件监听了。
2级事件监听移除的时候,必须“指名道姓”去移除。也就是说, 语法:

box.removeEventListener("click",boxClickHandler,true);

如果是匿名函数添加的事件监听,是不可能去掉的。

事件对象

事件对象概述

任何事件处理函数,系统都会自动向其传入一个event参数,封装这次事件的一些细节,如鼠标点击的位置等。

例子:通过div将event进行输出
测试效果

在这里插入图片描述

附上代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#box {
				width: 200px;
				height:200px;
				background-color: orange;
			}
		</style>
	</head>
	<body>
		<div id="box"></div>
		<script type="text/javascript">
			var box = document.getElementById("box");
			
			box.onclick = function(event) {
				console.log(event);
			}
		</script>
	</body>
</html>

event.target属性

    事件处理对象event对象一定有一个target属性,它表示事件阶段的最早来源。其含义是,若监听的是冒泡阶段,则event.target就是最内层元素,因为最内层元素就冒泡阶段的来源;而如果监听捕获阶段,则event.target是最外层元素,因为最外层元素就是捕获阶段的来源。

例子:利用按钮将event.target属性打印出来
测试效果

在这里插入图片描述
折用了0级别事件,因此输出按钮。

实验代码
<body>
	<div id="box1">
		<div id="box2">
			<button id="btn">按我</button>
		</div>
	</div>
	<script type="text/javascript">
		var box1 = document.getElementById("box1");
		var box2 = document.getElementById("box2");
		var btn = document.getElementById("btn");
		
		box1.onclick = function(event) {
			console.log(event.target);
		}
	</script>
</body>

阻止事件继续传播

事件流分为两个阶段,在捕获阶段,事件从最外层盒子传到最内层;在冒泡阶段,事件从最内层传到最外层。
     可以使用event.stopPropagation()来阻止事件继续传播.event对象是任何事件处理函数中的事件对象。

例子:用函数方法阻止单击继续弹盒子

在页面上制作3个盒子嵌套结构,分别是外层盒子box1、中层盒子box2、内层盒子box3,分别监听它们的捕获阶段的点击事件。
如果点击最内层盒子,按照正常情况先弹出“A”,然后“B”,然后“C”。但是在box2里做了事件阻塞,就不会弹出“C”框了。这就是阻止事件继续传播的妙用。

测试效果

在这里插入图片描述

附上代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			.box1 {
				width:300px;
				height: 300px;
				padding: 50px;
				background-color: skyblue;
			}
			.box2{
				width:160px;
				height:160px;
				padding:70px;
				background-color: purple;
			}
			.box3{
				width:55px;
				height:55px;
				padding:50px;
				background-color: orange;
			}
		</style>
	</head>
	<body>
		<div class="box1" id="box1">
			<div class="box2" id="box2">
				<div class="box3" id="box3"></div>
			</div>
		</div>
		<script type="text/javascript">
			var box1 = document.getElementById("box1");
			var box2 = document.getElementById("box2");
			var box3 = document.getElementById("box3");
			
			box1.addEventListener("click",function(){
				alert("A");
			},true);

			box2.addEventListener("click",function(){
				event.stopPropagation();
				alert("B");
			},true);
						
			box3.addEventListener("click",function(){
				alert("C");
			},true);			
		</script>
	</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值