JavaScript | 事件冒泡&捕获&委托

36 篇文章 1 订阅

1.冒泡:触发一个元素的事件时,该事件会向上(向父元素)传递

   <div class="parent">
		<ul class="news-list">
			<li><a href='#'>新闻</a></li>
			<li><a href='#'>体育</a></li>
			<li><a href='#'>财经</a></li>
		</ul>
	</div>

如上,触发<li>的点击事件时,同时也会触发<news-list>和<parent>...一直到<body>的点击事件,前提是这些父元素要绑定了点击事件且没有阻止冒泡。

2.捕获 :与冒泡相反,触发元素的事件时,会从根元素开始向目标元素一直传递事件。

 

3.事件委托(代理):

事件委托就利用了冒泡的机制,试想一下,我有一个<ul>,里面有成百上千个<li>,每个<li>对应一个点击链接,那么按照常规做法,我需要循环这些<li>,依次添加点击事件,这对性能是有很大影响的,如下:

	// 常规做法 遍历 li中的a标签 添加事件
	for(child of document.getElementsByClassName('news-list')[0].childNodes){
		if(child.childNodes.length){
			child.childNodes[0].addEventListener('click',function(e){
				console.log(this);
				//e.stopPropagation(); //阻止冒泡 不会传递回父元素
			})
		}
	}

另外,如果在这之后我们添加了新的<li>,新增的结点是不会注册该事件的

	 let LiItem=document.createElement("li")
	 LiItem.innerHTML = "<a href='#'>新增</a>"
 	 let dom = document.getElementsByClassName('news-list')[0];
	 dom.appendChild(LiItem) //没有触发事件

这时候事件委托(代理)就派上用场了,首先,事件委托的原理就是冒泡机制。在上述场景中,我们不再需要循环遍历<li>去注册事件,而是仅仅给父元素parent注册一个事件。

    // 先给父元素绑定事件
	document.getElementsByClassName('parent')[0].addEventListener('click',function(e){
		parFun(e);
	},false);

然后看看parFun做了什么

	function parFun(e) {
		var e = e || window.event;
		op  = e.target;

		console.log(e); //事件
		console.log(op); //触发事件的元素

		// 点到a才触发
		if(op.nodeName.toLowerCase()=='a'){
			console.log(op.innerText);
		}
	}

分析:首先要确认,这时候只有最外层的parent注册了点击事件,<li>甚至<ul>都没有注册事件,那么当我们点击<li>时,会依次触发父元素的点击事件,父元素ul没有注册点击事件,那么继续往上传递,找到<div class='parent'>,触发事件。这时候可以获取事件源e和触发事件的元素op,然后可以利用op进行判断是否要触发。

总结:事件委托利用了冒泡机制,避免了大量标签下的循环遍历注册事件,也避免了新增结点需要重新绑定事件的不便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值