JavaScript - 你知道事件委托的原理吗

难度级别:中级及以上                                 提问概率:55% 


说起事件委托,就要先说起Javascript的事件流。例如一个点击事件被触发后,会在父元素和子元素之间进行传递,从window对象,一直向下传递,传递到点击目标节点,这个阶段属于“捕获阶段”;事件在目标节点上被触发,这个小阶段属于“目标阶段”;紧接着点击事件从当前目标节点,又原路返回window对象,属于“冒泡阶段”。而事件委托使用的就是“冒泡”的原理。

那么事件委托可以用于哪些场景呢?例如图书录入功能中,有一个图书类型选择列表,希望用户点击每个类型的时候,记录下选中的类型值,用于后续的图书信息提交功能。最终生成的HTML片段代码如下

HTML代码:
<ul>
<li>科幻小说</li>
<li>冒险小说</li>
<li>童话故事</li>
<li>名人传记</li>
</ul> 

 最原始的理解应该是为每个类型li添加onclick事件,分别获取它的文字信息,代码如下

HTML代码:
<ul>
<li onclick="getBookType(event)">科幻小说</li>
<li onclick="getBookType(event)">冒险小说</li>
<li onclick="getBookType(event)">童话故事</li>
<li onclick="getBookType(event)">名人传记</li>
</ul>
Javascript代码:
<script>
function getBookType(event) {
let target = event.target || event.srcElement;
let bookType = target.innerText;
console.log(bookType);
}
</script>

但由于列表是动态的,可能不止这么4种类型,随时会增加,所以改进后的代码如下

HTML代码:
<ul>
<li>科幻小说</li>
<li>冒险小说</li>
<li>童话故事</li>
<li>名人传记</li>
</ul>
Javascript代码:
<script>
let lis = document.querySelectorAll('ul li');
for (let i=0;i<lis.length;i++) {
lis[i].onclick = function(e) {
console.log(e.target.innerText);
}
}
</script>

这种方法看似解决了问题,但却需要为每个子元素绑定事件,这种做法不仅消耗内存,而且动态添加子元素后需要再次执行代码从而获取lis集合。但如果使用事件委托的话,将事件绑定在父元素ul上,而不再是单独绑定在每个子元素li上,利用事件冒泡的机制,当事件响应到某个目标子元素的时候,其实是触发了外层父元素的绑定事件,本案例使用事件委托实现代码如下

Javascript代码:
<script>
let fatherUl = document.querySelector('ul');
fatherUl.addEventListener('click', function (e) {
let event = e || window.event;
let target = event.target || event.srcElement;
// 做到与目标元素的标签匹配
if (target.nodeName.toLowerCase() === 'li') {
console.log(target.innerText);
}
});
</script>

要注意,面试的时候先问一些知识的使用,再问原理或者优缺点,是很常见的套路。那么总结一下,事件委托有什么优点和缺点呢?优点其实已经很明显了,我们不需要把事件绑定到每个子元素上,而是绑定到了父元素上,这就使得子元素的增加或者删除都不需要再做额外的新增绑定和解绑工作,使得代码简单容易维护,使代码性能变高。但如果说到缺点的话,事件委托使用的是“冒泡”的原理,所以一旦子元素与真实绑定的父级元素离得过远的话,或者说中间嵌套层级比较多的话,冒泡就需要通过非常多的父元素,一直达到绑定事件的那个元素身上,这使得代码性能反而会降低。


刷题思考

    这道题主要在考察Javascript中事件委托的知识点,但想要回答好这道题,就需要更全面的掌握事件流、冒泡、捕获等一系列知识。当然,死记硬背面试题永远是不够的,对于这道面试题,面试官不会只让求职者回答类似事件流,先捕获后冒泡这一类理论知识的,它更希望听到在项目中的实际应用。

    一些高阶组件开发中,事件绑定、委派、委托都是特别常用的,所以如果能结合实际项目场景回答好这道题,面试官会认为求职者在代码层面上是有一点功底的。


类似考点

    事件流相关的考点在前端面试中频次很高,与之类似的考点还有很多,例如请说一说你在项目开发中是如何阻止冒泡的?例如你知道如何做到先冒泡,后捕获吗?例如你在项目中是如何使用事件委派的?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

经海路大白狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值