浅谈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中移除按钮也非常彻底。
浅谈JavaScript的事件(事件委托)的更多相关文章
- 浅谈JavaScript中的事件
引言 Html页面与JavaScript之间的交互是通过事件来完成的.事件,就是文档或者浏览器窗口中发生的一些特定的交互瞬间.可以使用侦听器(处理程序)来预订事件,以便事件发生时执行相应的代码.这在传 ...
- 浅谈Javascript单线程和事件循环
单线程 Javascript 是单线程的,意味着不会有其他线程来竞争.为什么是单线程呢? 假设 Javascript 是多线程的,有两个线程,分别对同一个元素进行操作: function change ...
- 浅谈javascript的Touch事件
js的touch事件,一般用于移动端的触屏滑动 代码如下: $(function(){ document.addEventListener("touchmove", _touch, ...
- 浅谈javascript函数节流
浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...
- 浅谈JavaScript中的闭包
浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...
- 浅谈JavaScript浮点数及其运算
原文:浅谈JavaScript浮点数及其运算 JavaScript 只有一种数字类型 Number,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的.浮点数的精度问题 ...
- 浅谈 JavaScript 编程语言的编码规范
对于熟悉 C/C++ 或 Java 语言的工程师来说,JavaScript 显得灵活,简单易懂,对代码的格式的要求也相对松散.很容易学习,并运用到自己的代码中.也正因为这样,JavaScript 的编 ...
- 浅谈javascript的原型及原型链
浅谈javascript的原型及原型链 这里,我们列出原型的几个概念,如下: prototype属性 [[prototype]] __proto__ prototype属性 只要创建了一个函数,就会为 ...
- 浅谈JavaScript中的null和undefined
浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...
- 浅谈JavaScript中的正则表达式(适用初学者观看)
浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...
随机推荐
- unittest编写Web测试用例
案例:百度搜索关键词:“unittest” test_baidu.py: from selenium import webdriver from time import sleep import un ...
- Builder(构造者)
Builder(构造者) <?php class Product { private $name; public function setName($name) { $this->name ...
- WPF ProgressBar 样式
<ProgressBar Grid.Row="2" Foreground="#45d207" IsIndeterminate="True&quo ...
- MySQL5.7 MTS work线程stack
复制现象是,slave线程状态正常,但是sql 线程不应用,所以delay越来越大,查看复制状态 mysql> show slave status\G********************** ...
- BZOJ 3566 [SHOI2014]概率充电器 ——期望DP
期望DP. 补集转化,考虑不能被点亮的情况, 然后就是三种情况,自己不能亮,父亲不能点亮它,儿子不能点亮它. 第一次计算比较容易,第二次计算的时候需要出去第一次的影响,因为一条线只能传导一次 #inc ...
- POJ 1860: Currency Exchange 【SPFA】
套汇问题,从源点做SPFA,如果有一个点入队次数大于v次(v表示点的个数)则图中存在负权回路,能够套汇,如果不存在负权回路,则判断下源点到自身的最长路是否大于自身,使用SPFA时松弛操作需要做调整 # ...
- eclipse中AXIS2发布过程
Axis2服务端研究好几个小时,终于解决了 需要下载: 地址1: 可以从镜像站下载: 上海大学开源镜像站 地址2: 链接:从百度网盘下载; 密码:8nwu 其中第二个可以不用下: 解压后 将3,4解压 ...
- poj 1031 多边形对点(向周围发射光线)的覆盖
Fence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 3018 Accepted: 1010 Description ...
- Java面试题集(二)
51.设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1,写出程序. 以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题. public class ThreadTest1 ...
- 转自CSDN,关于状态机
有限状态机FSM思想广泛应用于硬件控制电路设计,也是软件上常用的一种处理方法(软件上称为FMM--有限消息机).它把 复杂的控制逻辑分解成有限个稳定状态,在每个状态上判断事件,变连续处理为离散数字处理 ...