概述
事件委托还有一个名字叫事件代理。我们举一个例子去理解事件委托。公司有三个同事预计会在周一收快递。为签收快递,有两种方法:一是三个人在公司门口等快递;而是委托前台行政代为签收。现实中我们大多数采用第二种方案,前台行政收到快递后,她会判断收件人是谁,然后按照收件人的要求签收,甚至代付款。这种方案还要一个优势就是即使公司新来了员工,前台行政都会收到寄给新员工的快递后核实并代为签收。
这里其实还有2层意思的:
第一,现在委托前台的同事是可以代为签收的,即程序中的现有的dom节点是有事件的;
第二,新员工也是可以被前台MM代为签收的,即程序中新添加的dom节点也是有事件的。
为什么要用事件委托
我们预想两个场景
场景一
你要给100个按钮添加点击事件,怎么办?
当然可以用循环。但是在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因;如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;
每个函数都是一个对象,是对象就会占用内存,对象越多,内存占用率就越大,自然性能就越差了(内存不够用,是硬伤,哈哈),比如上面的100个li,就要占用100个内存空间,如果是1000个,10000个呢?
如果用事件委托,就简单方便了。那么我们就可以只对它的父级(如果只有一个父级)这一个对象进行操作,这样我们就需要一个内存空间就够了,是不是省了很多,自然性能就会更好。我们监听这100个按钮的祖先,等冒泡的时候判断target是不是这100个按钮中的一个。
场景二
你要监听目前不存在的元素的点击事件,怎么办?例如这个元素加了延时,要30秒后才创建
监听祖先,等点击的时候看看是不是我想要监听的元素即可
代码实现
div1.addEventListener('click',(e)=>{const t = e.targetif(t.tagName.toLowerCase() === 'button'){console.log('button被点击了')}})
