浅谈JavaScript的事件(事件委托)
事件处理程序为Web程序提供了系统交互,但是如果页面中的事件处理程序太多,则会影响页面的性能。每个函数都是对象,都会占用内存,内存中对象越多,性能越差。需要事先为DOM对象指定事件处理程序,导致访问DOM的次数增多,会延迟整个页面的交互就绪时间。
- 事件委托
对事件处理程序过多的解决方案是使用事件委托。事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。比如click事件会一直冒泡到document,也就是说我们只需为整个页面指定一个onclick事件处理程序,而不必为每个需要点击事件的元素单独添加。
<ul id="ul1">
<li id="li1">111</li>
<li id="li2">222</li>
</ul>
例如上面的代码,如果我们采用常规手段来添加事件处理程序,我们需要为每个li都添加事件。但是如果采用冒泡,我们只需要指定一个事件处理程序,并且能够实现同样的功能。
var oUl = document.getElementById("ul1");
EventUtil.addEvent(oUl, "click", function(ev) {
var ev = EventUtil.getEvent(ev);
var target = EventUtil.getTarget(ev);
if(target.id == 'li1') {
console.log("1");
}
else if(target.id=="li2"){
console.log("2");
}
});
上面的代码中,通过事件冒泡为ul1指定了事件处理程序,在我们单击li的时候通过事件冒泡也会触发该事件,并且能够通过target来获取当前单击的元素对象。通过元素id,为每个元素执行不同的if语句。
并不是所有的事件都适合使用事件委托,比较适用的事件是:mouseup、mousedown、click、keyup、keydown和keypress。虽然mouseover和mouseout也支持事件冒泡,但是如果使用事件委托则处理就比较麻烦,而且需要计算鼠标的位置以及元素的位置(当鼠标从一个元素移到其子节点,或者移出元素都会触发mouseout事件)。
var oUl = document.getElementById("ul1");
EventUtil.addEvent(oUl, "mouseout", function(ev) {
var ev = EventUtil.getEvent(ev);
var target = EventUtil.getTarget(ev);
if(target.id == 'li1') {
console.log("1");
}
else if(target.id=="li2"){
console.log("2");
}
});
比如上面的代码,当鼠标移到li元素的时候会触发mouseout,鼠标移出ul元素的时候也会触发mouseout事件。
- 移除事件处理程序
前文已经讲过事件的添加以及事件的移除。对于页面的事件处理程序太多,会影响页面的性能,除了使用事件委托之外,还可以将一些事件移除。内存中留有的一些过时的用不到的事件处理程序也是造成Web页面和内存性能的主要问题。
我们移除页面中的元素时候,可以通过removeChild和replaceChild方法,但有时候也会使用innerHTML来替换元素。如果某个元素有事件处理程序,通过innerHTML来替换,则事件处理程序依然存在,那么该事件处理程序已经使用不到,但是它也无法被回收,会一直占用内存空间。
<div id="firstdiv">
<input type="button" id="btnadd" value="添加" />
</div>
EventUtil.addEvent(document.getElementById("btnadd"),"click",function(event){
document.getElementById("firstdiv").innerHTML="processing";
});
上面的代码中为btnadd元素绑定了单击事件,单击的时候通过innerHTML移除了该元素,但是元素的事件处理程序并没有移除,依然留在内存中。
var callback =function(event){
EventUtil.removeEvent(document.getElementById("btnadd"),"click",callback);
document.getElementById("firstdiv").innerHTML="processing";
}
EventUtil.addEvent(document.getElementById("btnadd"),"click",callback);
上面的代码,我们在元素移除之前,手动移除了元素的事件处理程序。这样确保内存中也移除了该事件处理程序,而从DOM中移除按钮也非常彻底。
最新文章
- ASP.NET路由模型解析
- android copy项目后修改项目名
- Asp.Net 4.0 FormAuthentication 原理
- mac 终端乱码
- Jquery解析Json字符串,并且动态生成数据表格Table
- Weblogic12c安装与配置详解
- Spring核心框架 - AOP之动态代理机制
- to debug asp.net mvc4
- linux解压cpio.gz类型文件
- css基础-背景文本
- js中__proto__和prototype的区别和关系?
- 20170711_map/reduce
- MySQL 之 视图、触发器、存储过程、函数、事物与数据库锁
- C++框架_之Qt的窗口部件系统的详解-上
- Scrapy架构概述
- [LeetCode&;Python] Problem 101. Symmetric Tree
- Normalize.css &; Reset
- c# WPF RichTextBox 文字颜色
- 关于字符串 --java
- 基于SwiperJs的H5/移动端下拉刷新上拉加载更多