当前位置:网站首页>JS——事件代理和应用场景
JS——事件代理和应用场景
2022-07-23 21:47:00 【CaseyWei】

一、是什么
事件代理,俗地来讲,就是把一个元素响应事件(click、keydown......)的函数委托到另一个元素
前面讲到,事件流的都会经过三个阶段:捕获阶段 -> 目标阶段 -> 冒泡阶段,而事件委托就是在冒泡阶段完成
事件委托,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,而不是目标元素
当事件响应到目标元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数
下面举个例子:
比如一个宿舍的同学同时快递到了,一种笨方法就是他们一个个去领取
较优方法就是把这件事情委托给宿舍长,让一个人出去拿好所有快递,然后再根据收件人一一分发给每个同学
在这里,取快递就是一个事件,每个同学指的是需要响应事件的 DOM元素,而出去统一领取快递的宿舍长就是代理的元素
所以真正绑定事件的是这个元素,按照收件人分发快递的过程就是在事件执行中,需要判断当前响应的事件应该匹配到被代理元素中的哪一个或者哪几个
二、应用场景
如果我们有一个列表,列表之中有大量的列表项,我们需要在点击列表项的时候响应一个事件
<ul id="list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
......
<li>item n</li>
</ul>
如果给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的
// 获取目标元素
const lis = document.getElementsByTagName("li")
// 循环遍历绑定事件
for (let i = 0; i < lis.length; i++) {
lis[i].onclick = function(e){
console.log(e.target.innerHTML)
}
}
这时候就可以事件委托,把点击事件绑定在父级元素ul上面,然后执行事件的时候再去匹配目标元素
// 给父层元素绑定事件
document.getElementById('list').addEventListener('click', function (e) {
// 兼容性处理
var event = e || window.event;
var target = event.target || event.srcElement;
// 判断是否匹配目标元素
if (target.nodeName.toLocaleLowerCase === 'li') {
console.log('the content is: ', target.innerHTML);
}
});
还有一种场景是上述列表项并不多,我们给每个列表项都绑定了事件
但是如果用户能够随时动态的增加或者去除列表项元素,那么在每一次改变的时候都需要重新给新增的元素绑定事件,给即将删去的元素解绑事件
如果用了事件委托就没有这种麻烦了,因为事件是绑定在父层的,和目标元素的增减是没有关系的,执行到目标元素是在真正响应执行事件函数的过程中去匹配的
举个例子:
下面html结构中,点击input可以动态添加元素
<input type="button" name="" id="btn" value="添加" />
<ul id="ul1">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
使用事件委托
const oBtn = document.getElementById("btn");
const oUl = document.getElementById("ul1");
const num = 4;
//事件委托,添加的子元素也有事件
oUl.onclick = function (ev) {
ev = ev || window.event;
const target = ev.target || ev.srcElement;
if (target.nodeName.toLowerCase() == 'li') {
console.log('the content is: ', target.innerHTML);
}
};
//添加新节点
oBtn.onclick = function () {
num++;
const oLi = document.createElement('li');
oLi.innerHTML = `item ${num}`;
oUl.appendChild(oLi);
};
可以看到,使用事件委托,在动态绑定事件的情况下是可以减少很多重复工作的
三、总结
适合事件委托的事件有:click,mousedown,mouseup,keydown,keyup,keypress
从上面应用场景中,我们就可以看到使用事件委托存在两大优点:
减少整个页面所需的内存,提升整体性能
动态绑定,减少重复工作
但是使用事件委托也是存在局限性:
focus、blur这些事件没有事件冒泡机制,所以无法进行委托绑定事件mousemove、mouseout这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位,对性能消耗高,因此也是不适合于事件委托的
边栏推荐
- Protocol buffers 的问题和滥用
- [isprint function determines whether characters can be output]
- prime_ series_ level-1
- uniapp使用canvas写环形进度条
- 集群聊天服务器:数据库表的设计
- Apprentissage Lambda (utilisation du comparateur après tri, regroupement après collecte avec collectors.groupingby)
- 集群聊天服務器:數據庫錶的設計
- ESP32 的 I2C 原理 & 应用入门
- C - documents
- 大淘营批量采集商品,如何将未上传的宝贝保存下来等后面再导入采集上传
猜你喜欢

欧氏聚类(API)及其单木分割

节流和防抖的说明和实现

jedis 6---redisson和jedis的入门和不同

数据库系统概论第五版课后习题——第一章 绪论

A stack of digital robots were selected in Gartner's China AI market guide

大淘营批量采集商品,如何将未上传的宝贝保存下来等后面再导入采集上传

DBSCAN point cloud clustering

Cluster chat server: how to solve the problem of cross server communication | redis publish subscribe

HANA SQL 的Union和Union All

Unity - 3D mathematics -vector3
随机推荐
TreeMap
Summary of database stress testing methods
How to implement desktop lyrics in pyqt
Complete set of official openlayers instances
Apprentissage Lambda (utilisation du comparateur après tri, regroupement après collecte avec collectors.groupingby)
& 9 nodemon automatic restart tool
LeetCode_ 376_ Wobble sequence
集群聊天服务器为什么引入负载均衡器
【arxiv】第一次上传论文小记
Cluster chat server: cluster and distributed theory
Given an array composed of numbers, realize the name whose output ID is a number and sorted from small to large
Problems and abuse of protocol buffers
Boost Filesystem使用手册
集群聊天服务器:网络模块ChatServer
【HiFlow】腾讯云新一代自动化助手,我用它完成了企业疫情提示(无代码)
SQLite database
Basic knowledge of mobile phone testing
At 12 o'clock on July 23, 2022, the deviation from the top of the line of love life hour appeared, maintaining a downward trend and waiting for the rebound signal.
Chapter 2 Regression
淘宝助理停用,用大淘营导入数据包上传宝贝提示“主图为必填项,不能为空”是什么原因?如何解决?