js中的事件委托或是事件代理

您所在的位置:网站首页 appendchild是什么意思 js中的事件委托或是事件代理

js中的事件委托或是事件代理

2023-11-12 20:34| 来源: 网络整理| 查看: 265

直接看例子,我觉得非常好。

有3个同事预计会在周一收到快递,有2种方法,

1.一种是3个人都在公司门口等快递

2.委托给前台代收。

现实生活中,我们都采用委托的方案。等前台签收后,判断收件人是谁,然后按照收件人的要求签收,甚至代为付款。这种方案还有一个优势,那就是公司即使来了新员工(不管多少),前台都会统一签收

这里其实还有2层意思的:

第一:现在委托给前台同事代为签收,即程序中的现有dom节点是有事件的

第二:新员工也是可以被前台代收的,即程序中新添加的dom节点也是有事件的

为什么要用事件委托?

一般来说,dom需要有事件处理程序,我们都会直接给他设置事件处理程序就好,但是如果有很多个dom需要添加处理事件呢?比如我们有100个li,每个li都有相同的click事件,可能我们会用for循环的方法来遍历所有的li,然后给他们田间事件。

但是页面的事件处理程序会直接关系到也没的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重回与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少dom操作的原因;如果用事件委托,就会将所有的操作都放到js程序里面,与dom的操作就只需要交互一次,这样就能大大减少与dom的交互次数,提高性能;

每个函数都是一个对象,是对象就会占用内存,对象越多,内存占用率就越大,自然性能就越差了,比如上面的100个li,就要占用100个内存空间,如果是1000个,10000个呢?如果用事件委托,那么我们就可以只对它的父级这个对象进行操作,这样我们就需要一个内存空间就够了,性能就更好啦

事件委托的原理

事件委托市利用事件的冒泡原理来实现的。就是事件从最深的节点开始,然后逐步向上传播事件,比如:页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。

 

那么,事件委托怎么实现?

子节点实现相同的功能:

1111 2222 3333 4444

实现功能是点击li,弹出123

window.onload = function(){ var oUl = document.getElementById("ul1"); var aLi = oUl.getElementsByTagName("li"); for(var i=0;i aLi[i].onclick = function(){ alert(123); } }}

上面的demo很简单,相信很多人都是这么实现的,我们看看有多少次的dom操作,首先要找到ul,然后遍历li,然后点击li的时候,又要找一次目标li的位置,才能执行最后的操作,每次点击都要找一次li;

那么,我们用事件委托的方式做又会什么样呢?

window.onload = function(){ var oUl = document.getElementById("ul1"); oUl.onclick = function(){ alert(123) }}

这里用父级ul做事件处理,当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul有点击事件,所以事件就会被触发,当然,这里当点击ul的时候,那么问题来了,如果我想让事件代理的效果跟直接给节点的事件效果是一样怎么办?比如说只有点击li才会触发

Event对象提供了一个属性叫target,可以返回事件的目标节点,我们成为事件源,也就是说,target就可以表示为当前的事件操作dom,但是不是真正操作dom,当然,这个有兼容性的,标准浏览器ev.target,IE浏览器用event.srcElement,此时只是获取了当前节点的位置,并不知道是什么节点名称,这里我们用nodeName来获取具体是什么标签名,这个返回的是一个大写的,我们需要转成小写再做比较

window.onload = function(){ var oUl = document.getElementById("ul1"); oUl.onclick = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == 'li'){ alert(123); alert(target.innerHTML); } }

}

这样改下就只有点击li会触发事件了,且每次只执行一次dom操作,如果li数量很多的话,就大大减少dom操作,优化的性能可想而知!

上面的例子是说li操作的是同样的效果,要是每个li被点击的效果都不一样,那么用事件委托还有用吗?

window.onload = function() { var Add = document.getElementById("add"); var Remove = document.getElementById("remove"); var Move= document.getElementById("move"); var Select= document.getElementById("select"); Add.onclick = function(){ alert('添加'); }; Remove.onclick = function(){ alert('删除'); }; Move.onclick = function(){ alert('移动'); }; Select.onclick = function(){ alert('选择'); }

}

上面实现的效果我就不多说了,很简单,4个按钮,点击每一个做不同的操作,那么至少需要4次dom操作,如果用事件委托,能进行优化吗?

window.onload = function(){ var oBox = document.getElementById("box"); oBox.onclick = function(){ var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLocaleLowerCase() == 'input'){ switch(target.id){ case 'add': alert('添加'); break; case 'remove': alert('删除'); break; case 'move': alert('移动'); break; case 'select': alert('选择'); break;

} } }

}

用事件委托就可以只用一次dom操作就能完成所有的效果,比上面的性能肯定是要好一些的。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3