《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事件委托
元旦过后,新年第一篇. 初衷:很多的面试都会涉及到事件委托,前前后后也看过好多博文,写的都很不错,写的各有千秋,自己思前想后,为了以后自己的查看,也同时为现在找工作的前端小伙伴提供一个看似更全方位的解 ...
随机推荐
- sublime text 主题推荐
Soda Spacegray Flatland Tomorrow Base 16 Solarized Predawn itg.flat 其他所有的配色方案和主题.
- Lua学习系列(一)
从现在开始,打算学习一门新的脚本语言-lua. 1.什么是lua? a) lua1 • Lua 1.0 was implemented as a library, in less then 6000 ...
- VS2010与SVN
http://blog.sina.com.cn/s/blog_4fe44775010182yl.html 在VS2010中使用SVN,必须先安装SVN的客户端,再安装VisualSVN(SVN的插件) ...
- (简单) POJ 3074 Sudoku, DLX+精确覆盖。
Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgr ...
- CodeForces 450B Jzzhu and Sequences
矩阵快速幂. 首先得到公式 然后构造矩阵,用矩阵加速 取模函数需要自己写一下,是数论中的取模. #include<cstdio> #include<cstring> #incl ...
- java之常用正则表达式
http://www.cnblogs.com/helloczh/articles/1648029.html http://wenku.baidu.com/link?url=gLcsovVfQqRTVa ...
- VR元年,VR虚拟现实这只风口上的猪有怎样的变化?
走过了2016年,无论我们承认不承认,这一年到底是不是VR元年,我们都很难否定,在这一年,VR虚拟现实生态圈有很大的变化,那么,这一年VR虚拟现实到底有怎样的改变呢?我们的VR虚拟现实生态圈,发生了什 ...
- node.js 下依赖Express 实现post 4种方式提交参数
上面这个图好有意思啊,哈哈, v8威武啊.... 在2014年的最后一天和大家分享关于node.js 如何提交4种格式的post数据. 上上一篇说到了关于http协议里定义的4种常见数据的post方法 ...
- Tessnet2图片识别(2)
1. 引用 tessnet2.dll (只有NET2.0版本) 2. 视图页 <%@ Page Language="C#" MasterPageFile="~/Vi ...
- [git] 细说commit (git add/commit/diff/rm/reset 以及 index 的概念)
http://kasicass.blog.163.com/blog/static/39561920133294219374/ 创建测试仓库 $ git init $ echo "line o ...