事件处理程序为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中移除按钮也非常彻底。

浅谈JavaScript的事件(事件委托)的更多相关文章

  1. 浅谈JavaScript中的事件

    引言 Html页面与JavaScript之间的交互是通过事件来完成的.事件,就是文档或者浏览器窗口中发生的一些特定的交互瞬间.可以使用侦听器(处理程序)来预订事件,以便事件发生时执行相应的代码.这在传 ...

  2. 浅谈Javascript单线程和事件循环

    单线程 Javascript 是单线程的,意味着不会有其他线程来竞争.为什么是单线程呢? 假设 Javascript 是多线程的,有两个线程,分别对同一个元素进行操作: function change ...

  3. 浅谈javascript的Touch事件

    js的touch事件,一般用于移动端的触屏滑动 代码如下: $(function(){ document.addEventListener("touchmove", _touch, ...

  4. 浅谈javascript函数节流

    浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...

  5. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  6. 浅谈JavaScript浮点数及其运算

    原文:浅谈JavaScript浮点数及其运算     JavaScript 只有一种数字类型 Number,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的.浮点数的精度问题 ...

  7. 浅谈 JavaScript 编程语言的编码规范

    对于熟悉 C/C++ 或 Java 语言的工程师来说,JavaScript 显得灵活,简单易懂,对代码的格式的要求也相对松散.很容易学习,并运用到自己的代码中.也正因为这样,JavaScript 的编 ...

  8. 浅谈javascript的原型及原型链

    浅谈javascript的原型及原型链 这里,我们列出原型的几个概念,如下: prototype属性 [[prototype]] __proto__ prototype属性 只要创建了一个函数,就会为 ...

  9. 浅谈JavaScript中的null和undefined

    浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...

  10. 浅谈JavaScript中的正则表达式(适用初学者观看)

    浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...

随机推荐

  1. springboot集成redis操作

    使用HashOperations操作redis----https://www.cnblogs.com/shiguotao-com/p/10560458.html 使用HashOperations操作r ...

  2. Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / \ 9 20 / \

    class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vect ...

  3. MySQL5.7 服务 crash 后无法启动

    事发背景 测试环境更换数据盘,直接采取在线将数据目录暴力拷贝到新盘,然后将原服务关闭,启用新盘. 服务是可以正常启动的,但是没多会开发就反应服务down了,错误日志输出 -- :: InnoDB: F ...

  4. POJ 2888 Magic Bracelet ——Burnside引理

    [题目分析] 同样是Burnside引理.但是有几种颜色是不能放在一起的. 所以DP就好了. 然后T掉 所以矩阵乘法就好了. 然后T掉 所以取模取的少一些,矩阵乘法里的取模尤其要注意,就可以了. A掉 ...

  5. Spring的@Configuration来代替xml配置

    一. Xml配置法 下面是一个典型的spring配置文件(application-config.xml): [xml] view plain copy <beans> <bean i ...

  6. Spring Boot SpringSecurity5 身份验证

    对于没有访问权限的用户需要转到登录表单页面.要实现访问控制的方法多种多样,可以通过Aop.拦截器实现,也可以通过框架实现(如:Apache Shiro.Spring Security). pom.xm ...

  7. 作业调度方案(codevs 1156)

    题目描述 Description 我们现在要利用m台机器加工n个工件,每个工件都有m道工序,每道工序都在不同的指定的机器上完成.每个工件的每道工序都有指定的加工时间. 每个工件的每个工序称为一个操作, ...

  8. Spring学习之路——简单入门HelloWorld

    Spring简单介绍 Spring是一个提供了解决J2EE问题的一站式框架. Spring的核心是反转控制,通过配置文件完成业务对象之间的依赖注入,他鼓励一个良好的习惯,就是注入对接口编程而不是对类编 ...

  9. *hdu5632Rikka with Array

    $n \leq 10^300$,问所有$i<j$且$f_i>f_j$的$(i,j),1 \leq i \leq n,1 \leq j \leq n$数量.对某个数取模. $f(a,b,0/ ...

  10. java多线程总结一:线程的两种创建方式及比较

    1.线程的概念:线程(thread)是指一个任务从头至尾的执行流,线程提供一个运行任务的机制,对于java而言,一个程序中可以并发的执行多个线程,这些线程可以在多处理器系统上同时运行.当程序作为一个应 ...