浅谈JavaScript的事件(事件委托)

  事件处理程序为Web程序提供了系统交互,但是如果页面中的事件处理程序太多,则会影响页面的性能。每个函数都是对象,都会占用内存,内存中对象越多,性能越差。需要事先为DOM对象指定事件处理程序,导致访问DOM的次数增多,会延迟整个页面的交互就绪时间。

  • 事件委托

  对事件处理程序过多的解决方案是使用事件委托。事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。比如click事件会一直冒泡到document,也就是说我们只需为整个页面指定一个onclick事件处理程序,而不必为每个需要点击事件的元素单独添加。

1 <ul id="ul1">
2             <li id="li1">111</li>
3             <li id="li2">222</li>
4         </ul>

  例如上面的代码,如果我们采用常规手段来添加事件处理程序,我们需要为每个li都添加事件。但是如果采用冒泡,我们只需要指定一个事件处理程序,并且能够实现同样的功能。

 1 var oUl = document.getElementById("ul1"); 
 2             EventUtil.addEvent(oUl, "click", function(ev) {    
 3                 var ev = EventUtil.getEvent(ev);    
 4                 var target = EventUtil.getTarget(ev);    
 5                 if(target.id == 'li1') {       
 6                     console.log("1");   
 7                 }
 8                 else if(target.id=="li2"){
 9                     console.log("2");
10                 }  
11             });

  上面的代码中,通过事件冒泡为ul1指定了事件处理程序,在我们单击li的时候通过事件冒泡也会触发该事件,并且能够通过target来获取当前单击的元素对象。通过元素id,为每个元素执行不同的if语句。

并不是所有的事件都适合使用事件委托,比较适用的事件是:mouseup、mousedown、click、keyup、keydown和keypress。虽然mouseover和mouseout也支持事件冒泡,但是如果使用事件委托则处理就比较麻烦,而且需要计算鼠标的位置以及元素的位置(当鼠标从一个元素移到其子节点,或者移出元素都会触发mouseout事件)。

 1 var oUl = document.getElementById("ul1"); 
 2             EventUtil.addEvent(oUl, "mouseout", function(ev) {    
 3                 var ev = EventUtil.getEvent(ev);    
 4                 var target = EventUtil.getTarget(ev);    
 5                 if(target.id == 'li1') {       
 6                     console.log("1");   
 7                 }
 8                 else if(target.id=="li2"){
 9                     console.log("2");
10                 }  
11             });

  比如上面的代码,当鼠标移到li元素的时候会触发mouseout,鼠标移出ul元素的时候也会触发mouseout事件。

  • 移除事件处理程序

  前文已经讲过事件的添加以及事件的移除。对于页面的事件处理程序太多,会影响页面的性能,除了使用事件委托之外,还可以将一些事件移除。内存中留有的一些过时的用不到的事件处理程序也是造成Web页面和内存性能的主要问题。

  我们移除页面中的元素时候,可以通过removeChild和replaceChild方法,但有时候也会使用innerHTML来替换元素。如果某个元素有事件处理程序,通过innerHTML来替换,则事件处理程序依然存在,那么该事件处理程序已经使用不到,但是它也无法被回收,会一直占用内存空间。

1 <div id="firstdiv">
2             <input type="button" id="btnadd" value="添加" />
3         </div>
1 EventUtil.addEvent(document.getElementById("btnadd"),"click",function(event){
2                 document.getElementById("firstdiv").innerHTML="processing";
3             });

  上面的代码中为btnadd元素绑定了单击事件,单击的时候通过innerHTML移除了该元素,但是元素的事件处理程序并没有移除,依然留在内存中。

1 var callback =function(event){
2                 EventUtil.removeEvent(document.getElementById("btnadd"),"click",callback);
3                 document.getElementById("firstdiv").innerHTML="processing";
4             }
5             EventUtil.addEvent(document.getElementById("btnadd"),"click",callback);

  上面的代码,我们在元素移除之前,手动移除了元素的事件处理程序。这样确保内存中也移除了该事件处理程序,而从DOM中移除按钮也非常彻底。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏python3

tkinter -- Event(2)

特 殊 键Cancel/Break/BackSpace/Tab/Return/Sift_L/Shift_R/Control_L/Control_R/Alt_L/...

802
来自专栏Material Design组件

Material Design — 菜单(Menus)

42410
来自专栏CaiRui

HTML

超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言。 您可以使用 HTML 来建立自己的...

4198
来自专栏Java帮帮-微信公众号-技术文章全总结

开发者需要掌握的JS事件

JavaScript事件 ? 事件通常与函数配合使用,这样就可以通过发生的事件来驱动函数执行。事件是基于对象存在,事件通常可以修饰多种对象。 1.为对象添加事件...

4428
来自专栏从零开始学 Web 前端

从零开始学 Web 之 HTML5(二)表单,多媒体新增内容,新增获取操作元素,自定义属性

high:被界定为高的值的范围。 low:被界定为低的值的范围。 max:规定范围的最大值。 min:规定范围的最小值。 optimum: 规定度量的最...

1543
来自专栏python3

body标签中相关标签

字体标签包含:h1~h6、<font>、<u>、<b>、<strong><em>、<sup>、<sub>

1721
来自专栏柠檬先生

jquery mobile 移动web(3)

可折叠功能块。   div 元素的 data-role 属性设置为 collapsible   代码如下:     <div data-role="...

21010
来自专栏九彩拼盘的叨叨叨

Vue2 组件通信写法总结

子组件只接收在子组件定义的 props的值。通过 this.prop名称 获得父组件传数据。

622
来自专栏互联网杂技

接上一篇事件详解

事件类型: DOM3级事件规定了以下几类事件;如下: UI事件: 当用户与页面上的元素交互时触发; load事件:当页面加载完后(包括所有图像,所有javasc...

3696
来自专栏GIS讲堂

C#控件命名规范

1、 本规范是个人平时使用时为方便个人使用而制定的一套规范,有很多地方不易记忆与理解,后续在具体的使用过程中会做一定的改动。

2323

扫码关注云+社区

领取腾讯云代金券