Event处理
Event处理
今天抽时间写了一部分Event处理方面的函数愈发的觉得jQuery的优秀,自己前期的想法太粗糙,造成后面这些函数参数很多,操作很很不直观,看样子是要重构的节奏,还好小伙儿伴们安慰,架构都是改出来的。继续探索吧
浏览器兼容性
写Event处理的库函数一个难点就在于浏览器兼容性问题,在IE低版本浏览器中事件对象始终在window.event属性中,而在其它浏览器中event会作为事件处理程序中作为第一个参数传入。而且其Event对象的属性和方法也有诸多差异,在JavaScript与HTML交互——事件中基本有所总结,不过还是抄一段关于事件处理程序绑定方面的差异
1. 参数个数不相同,这个最直观,addEventListener有三个参数,attachEvent只有两个,attachEvent添加的事件处理程序只能发生在冒泡阶段,addEventListener第三个参数可以决定添加的事件处理程序是在捕获阶段还是冒泡阶段处理(我们一般为了浏览器兼容性都设置为冒泡阶段)
2. 第一个参数意义不同,addEventListener第一个参数是事件类型(比如click,load),而attachEvent第一个参数指明的是事件处理函数名称(onclick,onload)
3. 事件处理程序的作用域不相同,addEventListener得作用域是元素本身,this是指的触发元素,而attachEvent事件处理程序会在全局变量内运行,this是window,所以刚才例子才会返回undefined,而不是元素id
4. 为一个事件添加多个事件处理程序时,执行顺序不同,addEventListener添加会按照添加顺序执行,而attachEvent添加多个事件处理程序时顺序无规律(添加的方法少的时候大多是按添加顺序的反顺序执行的,但是添加的多了就无规律了),所以添加多个的时候,不依赖执行顺序的还好,若是依赖于函数执行顺序,最好自己处理,不要指望浏览器
最简单的四个
先写四个最简单的
- getEvent:获取事件对象
- getTarget:获取事件源对象
- preventDefault:阻止事件默认行为
- stopPropagation:阻止事件冒泡

(function (window) {
var ssLib = {
getEvent: function (e) {
return e ? e : window.event;
},
getTarget: function (e) {
var e = this.getEvent(e);
return e.target || e.srcElement;
},
preventDefault: function (e) {
var e = this.getEvent(e);
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
},
stopPropagation: function (e) {
var e = this.getEvent(e);
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
}
};
window.ssLib = window.ss = ssLib;
})(window);

代码很简单,相信聪明的小伙儿伴们一看就懂,就不多做解释了
addEvent/removeEvent
- addEvent:为元素绑定事件处理程序
- removeEvent:移除元素事件处理程序

addEvent: function (element, type, handler, key) {
var key = key || handler;
if (element[type + key])
return false;
if (typeof element.addEventListener != "undefined") {
element[type + key] = handler;
element.addEventListener(type, handler, false);
}
else {
element['e' + type + key] = handler;
element[type + key] = function () {
element['e' + type + key](window.event);
};
element.attachEvent('on' + type, element[type + key]);
}
return true;
},
removeEvent: function (element, type, key) {
if (!element[type + key])
return false;
if (typeof element.removeEventListener != "undefined") {
element.removeEventListener(type, element[type + key], false);
}
else {
element.detachEvent("on" + type, element[type + key]);
element['e' + type + key] = null;
}
element[type + key] = null;
return true;
},

这两个函数兼容性写法有很多,结合了很多大牛的写法后我用的上面版本,这么些看似很复杂,实际上主要解决了上面提到的、除了多个事件处理程序执行顺序问题的浏览器兼容性问题,比较难看懂的IE绑定部分就是为了处理this而写的。
在使用的时候,可以显示传入一个key用于内部识别绑定函数,如果不绑定则使用handler本身作为key,所以可以这么用

ssLib.addEvent(element,'click',function(){},'test');
ssLib.removeEvent(element,'click','test');
function handler(){}
ssLib.addEvent(element,'click',handler);
ssLib.removeEvent(element,'click',handler);

on/off
这个是看到jQuery的on/delegate和YUI 的delegate后萌发的想法,不过平时老用人家的没自己写过,仓促写了一个,感慨颇多,还是jQuery好使,这个版本目前有一定问题,明天优化一下

on: function (parent, type, handler,validater,key) {
var _key=key || handler;
parent['on'+type+_key]=function (e) {
var target = ssLib.getTarget(e);
var isFire = validater(target);
if (isFire) {
target[type + _key] = handler;
target[type + _key](e);
}
};
ssLib.addEvent(parent, type,parent['on'+type+_key] , key);
},
off: function (parent, type, key) {
if(typeof key=='function'){
ssLib.removeEvent(parent, type, parent['on'+type+key]);
}else{
ssLib.removeEvent(parent, type, key);
}
parent['on'+type+key]=null;
}

写法和刚才类似,不停的绕来绕去也是解决this问题,可以这么用
<div id="test">
<div id="t1">T1</div>
<div id="t2">T2</div>
</div>

var parent = document.getElementById('test');
var handler=function () {
alert(this.id);
}
var validater=function (obj) {
if(obj.parentNode.id=='test'){
return true;
}else{
return false;
}
}
ss.on(parent, 'click', handler, validater);
ss.off(parent,'click',handler);
ss.on(parent, 'click', handler, validater,'delegate');
ss.off(parent,'click','delegate');

ready
用过jQuery的同学肯定知道这个函数,写自己库的时候是各种惊羡啊,于是乎加到了自己的库里

ready: function (fn) {
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", function () {
document.removeEventListener("DOMContentLoaded", arguments.callee, false);// 防止多次调用
fn();
}, false);
} else if (document.addEvent) {
var doc = window.document, done = false;
// only fire once
var init = function () {
if (!done) {
done = true;
fn();
}
};
// polling for no errors
(function () {
try {
// throws errors until after ondocumentready
doc.documentElement.doScroll('left');// 文档加载完成后此方法可用
} catch (e) {
setTimeout(arguments.callee, 50);
return;
}
// no errors, fire
init();
})();
// trying to always fire before onload
doc.onreadystatechange = function () {
if (doc.readyState == 'complete') {
doc.onreadystatechange = null;
init();
}
};
}
}

要想看懂上面代码最好看看An alternative for DOMContentLoaded on Internet Explorer
最后
今天太晚了要去睡觉了,明天会优化一下代码并解释一下ready函数
Event处理的更多相关文章
- 如何利用ETW(Event Tracing for Windows)记录日志
ETW是Event Tracing for Windows的简称,它是Windows提供的原生的事件跟踪日志系统.由于采用内核(Kernel)层面的缓冲和日志记录机制,所以ETW提供了一种非常高效的事 ...
- [.NET] C# 知识回顾 - Event 事件
C# 知识回顾 - Event 事件 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6060297.html 序 昨天,通过<C# 知识回顾 - ...
- Atitit 解决Unhandled event loop exception错误的办法
Atitit 解决Unhandled event loop exception错误的办法 查看workspace/.metadata/.log org.eclipse.swt.SWTError: No ...
- Java模拟Windows的Event
场景 开发中遇到一个场景,业务操作会不定时的产生工作任务,这些工作任务需要放入到一个队列中,而另外会有一个线程一直检测这个队列,队列中有任务就从队列中取出并进行运算. 问题 业务场景倒是简单,只不过这 ...
- 事件EVENT与waitforsingleobject的使用
事件event与waitforsingleobject的配合使用,能够解决很多同步问题,也可以在数据达到某个状态时启动另一个线程的执行,如报警. event的几个函数: 1.CreateEvent和O ...
- 火狐浏览器中event不起作用解决办法--记录(一)
今天遇到了这个问题.IE,谷歌下都没问题,但在FF下却不起作用,很郁闷查了半天,看别人博文写了老长,结果试了要么起作用,但太麻烦,要么不起作用,说了那么多跟没说一样. 其实只要这一句代码就行:e=ar ...
- Event事件
妙味课堂-Event事件 1.焦点:当一个元素有焦点的时候,那么他就可以接受用户的输入(不是所有元素都能接受焦点) 给元素设置焦点的方式: 1.点击 2.tab 3.js 2.(例子:输入框提示文字) ...
- Event Sourcing Pattern 事件源模式
Use an append-only store to record the full series of events that describe actions taken on data in ...
- 严重: Exception sending context initialized event to listener instance of class
问题描述:Exception sending context initialized event to listener instance of class org.springframework.w ...
- [转载]C#委托和事件(Delegate、Event、EventHandler、EventArgs)
原文链接:http://blog.csdn.net/zwj7612356/article/details/8272520 14.1.委托 当要把方法作为实参传送给其他方法的形参时,形参需要使用委托.委 ...
随机推荐
- Git@OSC & SSH配置
#### [ 导入外部Git仓库到中国源代码托管平台(Git@OSC)] 免费代码托管 您可以通过SSH或者HTTP的方式提交和管理代码,也可以通过Web的方式在线阅读,编辑代码与Team@OSC的集 ...
- 管理员控制Windows Service
C# 以管理员方式启动Winform,进而使用管理员控制Windows Service 问题起因: 1,) 问题自动分析Windows服务在正常运行时,确实会存在程序及人为原因导致该服务停止.为了 ...
- firefox里面title乱码
原文:firefox里面title乱码 昨天 在notepad++里面写得文档里面title里面有中文,即使在文档里面写有charset=’UTF-8’, 但是保存后在firefox运行,浏览器标签标 ...
- 为什么使用Hystrix?
分布式服务弹性框架“Hystrix”实践与源码研究(一) 文章初衷 为了应对将来在线(特别是无线端)业务量的成倍增长,后端服务的分布式化程度需要不断提高,对于服务的延迟和容错管理将面临更大挑战,公 ...
- JS实现倒计时网页自动跳转(如404页面经常使用到的)
在web前端设计中,我们经常会遇到需要实现页面倒计时跳转的功能,例如在404页面中也会经常使用到此功能,那么如何实现呢,其实实现方法很简单,实现代码如下:<title>JS倒计时网页自动跳 ...
- TML5安全:CORS(跨域资源共享)简介
来源:http://blog.csdn.net/hfahe/article/details/7730944 前言:像CORS对于现代前端这么重要的技术在国内基本上居然很少有人使用和提及,在百度或者Go ...
- JS判断字符串是否全为中文
//第一种代码(全为中文则返回"true",不全为中文则返回"false"): <script language="javascript&quo ...
- loadrunner常用函数总结
事务函数:lr_end_sub_transaction 标记子事务的结束以便进行性能分析lr_end_transaction 标记 LoadRunner 事务的结束lr_end_transaction ...
- 关于winlogo.exe中了“落雪”病毒的解决方法
Windows Logon Process,Windows NT 用户登陆程序,管理用户登录和退出.该进程的正常路径应是 C:\Windows\System32 且是以 SYSTEM 用户运行,若不是 ...
- window批量-6 rem
行动: 凝视命令,加大对批量处理相应的描述性信息 格公式: rem [comment] demo: bat @echo off pause rem 这是对pause的解释 echo xxx pause ...