目录

 

概述

引入原因

具体写法

适用场景


概述

“事件处理程序过多”问题的解决方案就是事件委托,利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

事件冒泡:由接收事件的元素开始,向上逐渐传播。比如页面结构为document->html->body->div,当点击div时,首先触发div的click事件,然后click事件向上传播,在每一级上都会发生,直至传播到document对象。

引入原因

事件处理程序过多,会导致整体页面的运行性能。首先,每个函数都是对象,都会占用内存,内存中的对象越多,性能就越差;其次,必须事先指定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间。

<ul id="myList">
	<li id="item1">list item 1</li>
	<li id="item2">list item 2</li>
	<li id="item3">list item 3</li>
	<li id="item4">list item 4</li>
</ul>

如上述程序,假设每个li都有click点击事件:
①不用事件委托:我们要一个个获取到每个li再对它们添加click事件,要添加四个事件处理程序。
②使用事件委托:只需要在父节点即ul节点上添加事件,这样就只需要取得一个DOM结点,只添加一个事件处理程序。
②相较于①,结果相同,但需要的内存更少。

具体写法

根据上述程序:

<!-- ①不用事件委托 -->
var item1 = document.getElementById("item1");
var item2 = document.getElementById("item2");
var item3 = document.getElementById("item3");
var item4 = document.getElementById("item4");
item1.onclick = function(){
	console.log("I am item1");
}
item2.onclick = function(){
	console.log("I am item2");
}
item3.onclick = function(){
	console.log("I am item3");
}
item4.onclick = function(){
	console.log("I am item4");
}

<!-- 使用事件委托 -->
var myList = document.getElementById("myList");
myList.onclick = function(ev){
	var ev = ev || window.event;
  var target = ev.target || ev.srcElement;
  switch(target.id){
  	case "item1": 
  		console.log("I am item1");
  		break;
  	case "item2": 
  		console.log("I am item2");
  		break;
  	case "item3": 
  		console.log("I am item3");
  		break;
  	case "item4": 
  		console.log("I am item4");
  		break;
  }
}

适用场景

多数鼠标事件和键盘事件。最适合采用该技术的事件有click,mousedown,mouseup,keydown,keyup,keypress,而mouseover和mouseout事件也冒泡,但由于经常需要计算元素位置,因而要适当处理它们并不容易。

本面试题为前端常考面试题,后续有机会继续完善。我是歌谣,一个沉迷于故事的讲述者。

欢迎一起私信交流。

“睡服“面试官系列之各系列目录汇总(建议学习收藏)