js事件冒泡和捕获

👉 彻底弄懂js中事件冒泡和捕获是怎么回事

一、DOM事件触发经历的三个阶段

1、首先我们要弄清楚当一个dom事件被触发时,它不仅仅只是单纯地在自身对象上触发一次,而是经历了三个不同的阶段:👇
捕获阶段:先由文档的根节点document往事件触发对象,从外向内捕获事件对象;
目标阶段:到达目标事件位置,触发事件;
冒泡阶段:再从目标事件位置往文档的根节点方向回溯,从内向外冒泡事件对象。

2、下面贴上一张 w3c解释事件流 的图:
eventflow

二、冒泡和捕获

1、当我们注册一个事件时,事件默认使用冒泡事件流,不使用捕获事件流。

element.addEventListener(event, function, useCapture)

event: 必须。字符串,指定事件类型。
function: 必须。指定要事件触发时执行的函数。
useCapture: 可选。布尔值,指定事件是否在捕获或冒泡阶段执行。false为冒泡(默认),true为捕获。

2、下面在代码中验证,直接附上全部代码。(可以粘到自己编辑器中运行、尝试一下)

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>event</title>
	<style>
		#one{
			width: 600px;
			height: 600px;
			background-color: green;
		}
		#two{
			width: 400px;
			height: 400px;
			background-color: yellow;
		}
		#three{
			width: 200px;
			height: 200px;
			background-color: deepskyblue;
		}
	</style>
</head>
<body>
	<div id="one">one
		<div id="two">two
			<div id="three">three</div>
		</div>
	</div>

	<script>
		var one = document.getElementById('one'),
			two = document.getElementById('two'),
			three = document.getElementById('three');

		one.addEventListener('click', function(){
			console.log('one捕获')
		}, true)
		two.addEventListener('click', function(){
			console.log('two捕获')
		}, true)
		three.addEventListener('click', function(){
			console.log('three捕获')
		}, true)

		one.addEventListener('click', function(){
			console.log('one冒泡')
		}, false)
		two.addEventListener('click', function(){
			console.log('two冒泡')
		}, false)
		three.addEventListener('click', function(){
			console.log('three冒泡')
		}, false)

	</script>
</body>
</html>

3、当我们点击three时,可以看到确实是先由外向内事件捕获,一直到事发元素,再由内向外冒泡到根节点上。
capture
4、如果一个元素既注册了冒泡事件,也注册了捕获事件,则按照注册顺序执行。
我们修改代码把冒泡事件放在捕获事件之前:

		one.addEventListener('click', function(){
			console.log('one冒泡')
		}, false)
		two.addEventListener('click', function(){
			console.log('two冒泡')
		}, false)
		three.addEventListener('click', function(){
			console.log('three冒泡')
		}, false)
		
		one.addEventListener('click', function(){
			console.log('one捕获')
		}, true)
		two.addEventListener('click', function(){
			console.log('two捕获')
		}, true)
		three.addEventListener('click', function(){
			console.log('three捕获')
		}, true)

再点击three,可以看到这次three先是执行冒泡后捕获的,由此可见一个元素同时注册了冒泡和捕获事件,则会按照注册顺序执行。
capture

三、阻止事件冒泡

1、在很多时候我们并不需要元素绑定的事件向外冒泡,这时我们就要阻止事件的冒泡。
阻止冒泡:w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true;
我们再次修改代码,阻止three的事件冒泡:

		three.addEventListener('click', function(){
			console.log('three冒泡')
			var e = e || window.event; // firefox下window.event为null, IE下event为null
			// 阻止冒泡
			if(e.stopPropagation){
				e.stopPropagation()	//其他浏览器
			}else{
				e.cancelBubble = true //IE浏览器
			}			
		}, false)

修改完代码后我们再次点击three,可以看到three的点击事件触发后就停止继续向外冒泡了;
capture

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值