js的事件委托
2017-12-12 20:19
344 查看
在JavaScript中,添加到页面上的事件处理程序数量直接关系到页面的整体运行性能,导致这一问题的原因:1、每个函数都是对象,都会占用内存,内存中的对象越多,性能就越差;2、必须事先指定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间。
“事件委托”就是用于解决事件处理程序过多的问题,利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
比如:
按照传统做法,需要像下面这样为它们添加3个事件处理程序。使用事件委托,只需要在DOM树中尽量最高的层次上添加一个事件处理程序,例如:
--------------------------------------------------------------------------------------------以下摘自凌云之翼,如侵删------------------------------------------------------------------------------------------------------
现在讲的都是document加载完成的现有dom节点下的操作,那么如果是新增的节点,新增的节点会有事件吗?也就是说,一个新员工来了,他能收到快递吗?
看一下正常的添加节点的方法:
现在是移入li,li变红,移出li,li变白,这么一个效果,然后点击按钮,可以向ul中添加一个li子节点
这是一般的做法,但是你会发现,新增的li是没有事件的,说明添加子节点的时候,事件没有一起添加进去,这不是我们想要的结果,那怎么做呢?一般的解决方案会是这样,将for循环用一个函数包起来,命名为mHover,如下:
虽然功能实现了,看着还挺好,但实际上无疑是又增加了一个dom操作,在优化性能方面是不可取的,那么有事件委托的方式,能做到优化吗?
看,上面是用事件委托的方式,新添加的子元素是带有事件效果的,我们可以发现,当用事件委托的时候,根本就不需要去遍历元素的子节点,只需要给父级元素添加事件就好了,其他的都是在js里面的执行,这样可以大大的减少dom操作,这才是事件委托的精髓所在。
“事件委托”就是用于解决事件处理程序过多的问题,利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
比如:
<ul id ="myLinks"> <li id="dosomething">something</li> <li id="buysomething">something</li> <li id="gosomething">something</li> </ul>
按照传统做法,需要像下面这样为它们添加3个事件处理程序。使用事件委托,只需要在DOM树中尽量最高的层次上添加一个事件处理程序,例如:
var list =document.getElementById("myList"); EventUtil.addHandler(list,"click",function(event){ event = EventUtil.getEvent(event); var target = EventUtil.getTarget(event); switch(target.id){ case "dosomething": document.title = "I changed the document`s title"; break; case "gosomething": location.href = "http://www.baidu.com"; break; case "buysomething": alert("buy sth"); break; } })在这段代码中,我们使用事件委托只为<ul>元素添加了一个onclick事件处理程序。由于所有列表项都是这个元素的子节点,而且他们的事件会冒泡,所以单击事件最终会被这个函数处理,可以通过检测id属性来决定采取适当的操作。这种方法对用户来说最终的结果相同,但是只取得了一个DOM元素,只添加了一个事件处理程序,占用的内存更少。
--------------------------------------------------------------------------------------------以下摘自凌云之翼,如侵删------------------------------------------------------------------------------------------------------
现在讲的都是document加载完成的现有dom节点下的操作,那么如果是新增的节点,新增的节点会有事件吗?也就是说,一个新员工来了,他能收到快递吗?
看一下正常的添加节点的方法:
<input type="button" name="" id="btn" value="添加" /> <ul id="ul1"> <li>111</li> <li>222</li> <li>333</li> <li>444</li> </ul>
现在是移入li,li变红,移出li,li变白,这么一个效果,然后点击按钮,可以向ul中添加一个li子节点
window.onload = function(){ var oBtn = document.getElementById("btn"); var oUl = document.getElementById("ul1"); var aLi = oUl.getElementsByTagName('li'); var num = 4; //鼠标移入变红,移出变白 for(var i=0; i<aLi.length;i++){ aLi[i].onmouseover = function(){ this.style.background = 'red'; }; aLi[i].onmouseout = function(){ this.style.background = '#fff'; } } //添加新节点 oBtn.onclick = function(){ num++; var oLi = document.createElement('li'); oLi.innerHTML = 111*num; oUl.appendChild(oLi); }; }
这是一般的做法,但是你会发现,新增的li是没有事件的,说明添加子节点的时候,事件没有一起添加进去,这不是我们想要的结果,那怎么做呢?一般的解决方案会是这样,将for循环用一个函数包起来,命名为mHover,如下:
window.onload = function(){ var oBtn = document.getElementById("btn"); var oUl = document.getElementById("ul1"); var aLi = oUl.getElementsByTagName('li'); var num = 4; function mHover () { //鼠标移入变红,移出变白 for(var i=0; i<aLi.length;i++){ aLi[i].onmouseover = function(){ this.style.background = 'red'; }; aLi[i].onmouseout = function(){ this.style.background = '#fff'; } } } mHover (); //添加新节点 oBtn.onclick = function(){ num++; var oLi = document.createElement('li'); oLi.innerHTML = 111*num; oUl.appendChild(oLi); mHover (); }; }
虽然功能实现了,看着还挺好,但实际上无疑是又增加了一个dom操作,在优化性能方面是不可取的,那么有事件委托的方式,能做到优化吗?
window.onload = function(){ var oBtn = document.getElementById("btn"); var oUl = document.getElementById("ul1"); var aLi = oUl.getElementsByTagName('li'); var num = 4; //事件委托,添加的子元素也有事件 oUl.onmouseover = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == 'li'){ target.style.background = "red"; } }; oUl.onmouseout = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == 'li'){ target.style.background = "#fff"; } }; //添加新节点 oBtn.onclick = function(){ num++; var oLi = document.createElement('li'); oLi.innerHTML = 111*num; oUl.appendChild(oLi); }; }
看,上面是用事件委托的方式,新添加的子元素是带有事件效果的,我们可以发现,当用事件委托的时候,根本就不需要去遍历元素的子节点,只需要给父级元素添加事件就好了,其他的都是在js里面的执行,这样可以大大的减少dom操作,这才是事件委托的精髓所在。
相关文章推荐
- js中的事件委托
- js事件捕获,事件冒泡,事件委托以及DOM事件流
- JS事件委托
- js 事件代理(事件委托)
- js中的事件委托
- js中的事件委托
- js为动态添加的元素增加事件(事件委托)
- js动态添加事件-事件委托
- js实例分析JavaScript中的事件委托和事件绑定
- js中的事件委托详解
- div获取焦点响应事件失效及js事件委托机制
- js中的事件委托或是事件代理详解
- js委托事件-addEventListeners(冒泡方向)
- 利用事件委托解决js元素添加后未响应绑定事件问题
- 前端JS面试题汇总 Part 1(事件委托/this关键字/原型链/AMD与CommonJS/自执行函数)
- js 事件委托
- 【javascript】js事件委托
- js的事件委托
- js中的事件委托
- js事件委托的总结