js中的事件委托或是事件代理 |
您所在的位置:网站首页 › appendchild是什么意思 › js中的事件委托或是事件代理 |
直接看例子,我觉得非常好。 有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 |