《JAVASCRIPT高级程序设计》事件委托和模拟事件
由于事件处理程序可以为现代web应用提供交互能力,因此许多开发人员不分青红皂白向页面中添加大量的处理程序;这在某些语言中不会导致问题,但是在javascript,事件处理程序数量直接关系到页面的整体运行性能。因为,首先每个函数都是对象,都会占用内存,内存中对象越多,性能就越差;其次,必须事先指定所有事件处理程序而导致的dom访问次数,会延迟整个页面的交互就绪时间。
一、事件委托
对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了冒泡事件,只指定一个事件处理程序,就可以管理某一类型的所有事件。
<html>
<head>
<meta charset="utf-8">
<title>事件委托</title>
</head>
<body>
<ul id="myLinks">
<li id="Gosomewhere">Go somewhere</li>
<li id="dosomething">Do something</li>
<li id="sayhi">Say hi</li>
</ul>
<script>
// 跨浏览器的事件处理程序
var EventUtil = {
addHandler:function(element, type, handler){
if(element.addEventListener){
// DOM2级事件
element.addEventListener(type, handler, false);
}else if(element.attachEvent){
// IE事件
element.attachEvent(on+"type", handler);
}else{
// DOM0级事件
element["on"+type] = handler;
}
},
removeHandler:function(element, type, handler){
if(element.removeEventListener){
// DOM2级事件
element.removeEventListener(type, handler, false);
}else if(element.detachEvent){
// IE事件
element.detachEvent(on+"type", handler);
}else{
// DOM0级事件
element["on"+type] = null;
}
},
getEvent:function(event){
return event? event:window.event;
},
getTarget:function(event){
return event.target || event.srcElement;
}
};
var list = document.getElementById("myLinks");
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 title."
break;
case "Gosomewhere":
self.location.href = "http://www.baidu.com";
break;
case "sayhi":
alert("hi");
break;
}
});
</script>
</body>
</html>
这段代码只取得了一个DOM元素,只添加了一个事件处理程序,占用的内存也更少。最适合采用事件委托的事件包括:click, mousedown,mouseup,keydown,keyup和keypress。虽然mouseover和mouseout事件也冒泡,但要适当处理他们并不容易,而且需要经常计算元素的位置。
二、移除事件处理程序
在不需要事件处理程序的时候把它们移除,能够提高页面的性能。内存中留有过时不用的“空事件处理程序”,也是造成web应用程序与性能问题的主要原因。在两种情况下,会造成上述原因:
1、从文档中移除带有事件处理的元素时,如果元素被innerHTML删除,那么原来添加到元素中的事件处理程序极有可能无法被当做垃圾回收;---------如果你知道某个元素即将被移除,最好手工移除事件处理程序;
2、如果在页面卸载之前没有清理干净事件处理程序,那么页面卸载后,它们就会滞留在内存中。每次页面来回切换或点击了刷新时,内存中滞留的事件数目就会增加,因此为事件处理程序的内存并没有被释放。--------最好的做法是在页面卸载之前,先通过onunload移除所有的事件处理程序。
三、模拟事件
事件经常由用户操作或者通过其他浏览器功能来触发,也可以使用javascript在任意时刻触发特定的事件。在测试web应用程序时,模拟触发事件是一件及其有用的技术;DOM2规定了模拟事件的方式,IE也有自己模拟事件的方式,下面分别介绍:
1、在DOM中的事件模拟
在DOM中,可以使用createEvent()创建event对象,这个方法接收一个参数,即表示的要创建的事件类型的字符串。这个字符串可以是以下几个之一:
- UIEvents:一般化的UI事件
- MouseEvents:一般化的鼠标事件
- MutationsEvents:一般化的DOM变动事件
- HTMLEvents:一般化的HTML事件
在创建了event对象后,需要使用与事件有关的信息初始化,最后需要使用dispatchEvent()来触发事件。
1)模拟鼠标事件
var btn = document.getElementById("myBtn");
// 创建事件对象
var event = document.createEvent("MouseEvents");
// 初始化事件对象
// 该函数接受15个参数,分别于鼠标事件的典型属性相对应,例如,是否按下了alt键等
event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0,
false, false, false, false, 0, null);
// 触发事件
btn.dispatchEvent(event);
2)键盘模拟事件
由于DOM2级事件中,没有就键盘事件作出规定,因此只能使用DOM3级事件;在使用前,应该先检测浏览器是否支持DOM3级事件。
// 以DOM3级别的方式创建事件对象
if(document.implementation.hasFeature("keyboardEvents", "3.0")){
var event = document.createEvent("keyboardEvents");
}
// 初始化事件对象
// 该函数接受一系列与键盘属性相关的参数
event.initKeyboardEvent("keydown", true, true, document.defaultView, "a",0, "Shift", 0);
// 触发事件
textbox.dispatchEvent(event);
2、在IE中的事件模拟
在IE中,可以通过document.createEventObject()创建event对象,然后手工为这个对象添加所有需要的信息,最后是调用fireEvent方法触发事件。
var btn = document.getElementById("myBtn");
//创建事件对象
var event = document.createEventObject();
// 初始化事件对象,模拟在一个按钮上触发click事件的过程
event.screenX = 100;
event.screenY = 0;
event.clientX = 0;
event.clientY = 0;
event.ctrlKey = false;
event.altKey = false;
event.shiftKey = false;
event.button = 0;
// 触发事件
btn.fireEvent("onclick", event);
《JAVASCRIPT高级程序设计》事件委托和模拟事件的更多相关文章
- 读书笔记(05) - 事件 - JavaScript高级程序设计
HTML依托于JavaScript来实现用户与WEB网页之间的动态交互,接收用户操作并做出相应的反馈,而事件在此间则充当桥梁的重要角色. 日常开发中,经常会为某个元素绑定一个事件,编写相应的业务逻辑, ...
- JavaScript高级程序设计-13:事件
JavaScript与HTML之间的交互是通过事件实现的. 一.事件流 首先我们要明白事件流的概念.当我们点击一个按钮时,也点击了按钮的容器元素,甚至也点击了整个事件.事件流描述就是从页面中接收事件的 ...
- javaScript事件机制深入学习(事件冒泡,事件捕获,事件绑定方式,移除事件方式,阻止浏览器默认行为,事件委托,模拟浏览器事件,自定义事件)
前言 JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间.可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码.这种在传统软 ...
- 《javascript高级程序设计》 touch事件的一个小错误
最近一段时候都在拜读尼古拉斯大神的<javascript高级程序设计>,真的是一本好书,通俗易懂,条理比<javascript权威指南>好理解一些,当然<javascri ...
- JavaScript高级程序设计学习笔记--事件
HTML事件处理程序 <input type="button" value="Click Me" onclick"showMessage()&q ...
- JavaScript高级程序设计笔记 事件冒泡和事件捕获
1.事件冒泡 要理解事件冒泡,就得先知道事件流.事件流描述的是从页面接收事件的顺序,比如如下的代码: <body> <div> click me! </div> & ...
- javascript事件委托和jQuery事件绑定on、off 和one
一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...
- javascript 事件委托 和jQuery事件绑定on、off 和one
一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...
- javascript事件委托和jquery事件委托
元旦过后,新年第一篇. 初衷:很多的面试都会涉及到事件委托,前前后后也看过好多博文,写的都很不错,写的各有千秋,自己思前想后,为了以后自己的查看,也同时为现在找工作的前端小伙伴提供一个看似更全方位的解 ...
随机推荐
- Spark+ECLIPSE+JAVA+MAVEN windows开发环境搭建及入门实例【附详细代码】
http://blog.csdn.net/xiefu5hh/article/details/51707529 Spark+ECLIPSE+JAVA+MAVEN windows开发环境搭建及入门实例[附 ...
- STM32驱动TEA5767收音机模块
Tea5767是飞利浦公司出的一款集成化的收音机芯片,大四的时候机缘巧合遇到了这个芯片,用了一下,写点资料 主要特性 TEA5767HN是一款低功耗立体声收音IC,广泛应用于手机MP3 .MP 4 播 ...
- iOS开发——汉字转拼音
以前有一次做一个天气预报的项目,有一个功能是输入城市名,请求该城市的天气,需要把汉字转化成拼音,比如深圳——>shenzhen,加入到参数中.当时在网上找了一下,网友给出的方法很多都用不了,现在 ...
- IOS9新特性之Contacts联系人
在以前iOS开发中,涉及联系人相关的编程,代码都非常繁琐,并且框架的设计也不是Objective-C风格的,这使开发者用起来非常的难受.在iOS9中,apple终于解决了这个问题,全新的Contact ...
- 安卓组件service
[转]http://blog.csdn.net/ithomer/article/details/7364024 一. Service简介 Service是android 系统中的四大组件之一(Acti ...
- c#第5章 变量的更多内容 隐式和显式转换、枚举、结构、数组、
1.目标数据 destination 英[ˌdestɪˈneɪʃn] 美[ˌdɛstəˈneʃən] n. 目的,目标; 目的地,终点; [罕用语] 预定,指定; 2.源数据 source 英[sɔ: ...
- Python的zip函数
zip函数接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表.具体意思不好用文字来表述,直接看示例: 1.示例1: x = [1, 2, 3] y = [4, 5, 6] z = [7 ...
- Javascript 查找元素
DOM定义了多种查找元素的方法,除了我们常用的getElementById(),还有getElementsByTagName()和getElementsByName().使用这几种方法方法我们可以查找 ...
- R语言中的if-else语句写法
结构 1 : if() xx else yy 一行: 结构 2: if() {xx} else {yy} 或者 if(){ xx }else #此处不能两行写 ...
- 创业类网站建设日志1——搭建服务器svn以及前端开发环境
1.需要在linux环境的服务器下搭建node和npm还有Grunt,所以先需要一个叫putty的工具连接服务器命令行终端 2.双击putty工具,在HostName一栏输入项目服务器地址:172.1 ...