当前位置: 首页 > Web前端 > vue.js

js中的事件委托-代理

时间:2023-03-31 22:54:05 vue.js

今天在做项目的时候,在项目的评论里发现了一条关于事件委托的评论(PS:虽然下面的代码不是事件委托的代码图),小编作为一个做了三四年前端的菜鸟,还不知道什么是事件委托,想了想,惭愧,特意把这个插在了Vue3专栏的中间。既然说到事件委托,就不得不提到冒泡,那么什么是事件冒泡呢?小编特意在网上找了这么一张图。底部的气泡很小,越往上气泡越大。图中的气泡可以看作是html中的DOM结构。那么究竟什么是冒泡呢?比如这样的结构第一个元素第二个元素第三个元素

同样我们定义三个对应的函数functionhandleDivClick(){alert('handleDivClick')}functionhandleUlClick(){alert('handleUlClick')}functionhandleLiClick(){alert('handleLiClick')}这时候我们再次点击li元素的时候,除了执行它自己的点击函数外另外,会执行ul和div元素的点击功能,即点击一次,会出现三个弹窗。这就是小编??理解的冒泡。同样,在原生js中,提供了e.stopPropagation()(W3C)和e.cancelBubble=true(IE)来防止事件冒泡。对于Vue,.stop修改也提供了符号。以下内容转载自https://www.cnblogs.com/lauzh...那么什么是事件委托呢?它还有一个名字叫做事件代理。从高级JavaScript编程的角度来看:事件委托使用事件冒泡,通过只指定一个事件处理程序来管理某一类型的所有事件。那么这是什么意思?网上所有高手基本都是用同一个事件委托的例子,就是拿快递来解释这个现象。仔细想了想,发现这个例子真的很贴切。我不会想到其他例子来解释它。借花供佛,我去取了,大家认真了解一下活动委托的原则:三位同事预计周一收到快递。快递签收有两种方式:一种是三个人在公司门口等快递;另一种是委托前台MM签收。现实中,我们大多采用委托解决(公司不会容忍那么多员工站在门口等快递)。前台MM收到快递后,会判断收件人是谁,然后根据收件人的要求签收,甚至代付。这种方案还有一个好处就是,即使公司有新员工(不管多少),前台MM收到新员工寄来的快递后,也会核实签收。这里其实有两层意思:第一,前台的同事现在可以代为签收,即程序中已有的dom节点有事件;第二,新员工也可以通过前台MM签到,即程序中新添加的dom节点也有事件。为什么要使用事件委托:一般来说dom是需要有事件处理器的,我们直接给它设置事件处理器就好了,如果dom很多需要添加事件处理器怎么办?比如我们有100里,每里都有相同的点击事件。可能我们会用for循环的方式遍历所有的lis,然后给它们添加事件。会有什么影响?在JavaScript中,添加到页面的事件处理程序的数量会直接影响页面的整体性能,因为需要不断地与dom节点进行交互,访问dom的次数越多,浏览器重绘和重排的次数就会越多越来越多,会延长整个页面的交互就绪时间,这也是为什么性能优化的主要思路之一就是减少DOM操作;如果要使用事件委托,则将所有操作都放在js程序中,与dom的操作只需要交互一次,可以大大减少与dom的交互次数,提高性能;每个函数都是一个对象,对象会占用内存。对象越多,占用内存越大,性能自然会变差(内存不够,是硬伤,哈哈),比如上面的100里会占用100个内存空间,如果是1000,10000,那只能说哈哈,如果使用事件委托,那我们就只能操作它parent的对象了(如果parent只有一个的话),这样我们只需要一个内存空间,是不是省了很多,自然性能会更好。事件委托的原理:事件委托是利用事件冒泡的原理实现的。什么是事件冒泡?意思是事件从最深的节点开始,然后逐渐向上传播事件。比如:页面上有这么一个节点树,div>ul>li>a;比如在最里面的a添加一个click事件,那么这个事件就会一层层执行,执行顺序是a>li>ul>div。有这么一个机制,那么我们在最外层的div中添加一个点击事件,当里面的ul、li、a都是点击事件的时候,它们都会Bubbles到最外层的div,所以才会触发。这就是事件委托,委托父母代为执行事件。如何实现事件委托:终于到了本文的核心部分,哈哈,在介绍事件委托的方法之前,先看一个通用方法的例子:子节点实现同样的功能:
  • 111
  • 222
  • 333
  • 444
  • 实现功能是点击li,弹出123:窗口.onload=function(){varoUl=document.getElementById("ul1");varaLi=oUl.getElementsByTagName('li');for(vari=0;i
    window.onload=function(){varAdd=document.getElementById("添加");varRemove=document.getElementById("删除");varMove=document.getElementById("移动");varSelect=document.getElementById("选择");Add.onclick=function(){alert('添加');};Remove.onclick=function(){alert('删除');};Move.onclick=function(){alert('移动');};Select.onclick=function(){alert('select');}}上面实现的效果就不多说了,很简单,4个按钮,点击每个按钮做不同的操作,那么至少需要4次dom操作,如果使用事件委托,能不能优化一下?window.onload=function(){varoBox=document.getElementById("box");oBox.onclick=function(ev){varev=ev||窗口事件;vartarget=ev.目标||ev.srcElement;if(target.nodeName.toLocaleLowerCase()=='input'){switch(target.id){case'add':alert('add');休息;案例“删除”:警报(“删除”);休息;案例“移动”:警报(“移动”);休息;案例“选择”:警报(“选择”);休息;}}}}你只能使用事件委托做一次m操作可以完成所有的效果,肯定比上面的性能要好。下面我们说的是文档加载完成后在已有dom节点下的操作。如果是新节点,新节点会有事件。?也就是说,如果有新员工来了,他能收到快递吗?看一下正常的添加节点的方法:
  • 111
  • 222
  • 333
  • 444
  • 现在移入li,li变红,移出li,li变白,这样的效果,和然后点击按钮,就可以给ul添加一个li子节点window.onload=function(){varoBtn=document.getElementById("btn");varoUl=document.getElementById("ul1");varaLi=oUl.getElementsByTagName('li');变量数=4;//鼠标移进去变成红色,移出变成白色for(vari=0;i