您的位置:知识库 » Web前端

事件模块的演变

作者: snandy  来源: 博客园  发布时间: 2011-04-12 10:40  阅读: 2055 次  推荐: 0   原文链接   [收藏]  

  上一篇中的add有个问题,对同一类型事件添加多个hanlder时,IE6/7/8下会无序,如:

<div id="d1" style="width:200px;height:200px;background:gold;"></div>
<script type="text/javascript">
var el = document.getElementById('d1');
function handler1(){alert('1');}
function handler2(){alert('2');}
function handler3(){alert('3');}
function handler4(){alert('4');}
function handler5(){alert('5');}
E.add(el,
'click', handler1);
E.add(el,
'click', handler2);
E.add(el,
'click', handler3);
E.add(el,
'click', handler4);
E.add(el,
'click', handler5);
</script>

  IE9/Firefox/Safari/Chomre/Opera会依次输出1,2,3,4,5。但IE6/7/8中则不一定。为解决所有浏览器中多个事件handler有序执行,我们需要一个队列来管理所有的handler。

  这次,把所有的内部细节封装在一个匿名函数中,该函数执行完毕后返回如上一篇接口相同的方法。另外

  1,把真正的事件handler挂在el上,即el.listeners,其为一个对象,每一个类型的事件为一个数组,如click为el.listeners["click"] = []。

  2,所有的handler存在在对于的数组中

  3,删除一个hanlder,将从数组中将其删除

E = function(){
function _isEmptyObj(obj){
for(var a in obj){
return false;
}
return true;
}
function _each(ary, callback){
for(var i=0,len=ary.length; i<len;){
callback(i, ary[i])
? i=0 : i++;
}
}
function _remove(el, type){
var handler = el.listeners[type]['_handler_'];
el.removeEventListener
?
el.removeEventListener(type, handler,
false) :
el.detachEvent(
'on'+type, handler);
delete el.listeners[type];
if(_isEmptyObj(el.listeners)){
delete el.listeners;
}
}
// 添加事件
function add(el, type, fn){
el.listeners
= el.listeners || {};
var listeners = el.listeners[type] = el.listeners[type] || [];
listeners.push(fn);
if(!listeners['_handler_']){
listeners[
'_handler_'] = function(e){
var evt = e || window.event;
for(var i=0,fn; fn=listeners[i++];){
fn.call(el, evt);
}
}
el.addEventListener
?
el.addEventListener(type, listeners[
'_handler_'], false) :
el.attachEvent(
'on' + type, listeners['_handler_']);
}
}
// 删除事件
function remove(el, type, fn){
if(!el.listeners) return;
var listeners = el.listeners && el.listeners[type];
if(listeners) {
_each(listeners,
function(i, f){
if(f==fn){
return listeners.splice(i, 1);
}
});
if(listeners.length == 0){
_remove(el,type);
}
}
}
//主动触发事件
function dispatch(el ,type){
try{
if(el.dispatchEvent){
var evt = document.createEvent('Event');
evt.initEvent(type,
true,true);
el.dispatchEvent(evt);
}
else if(el.fireEvent){
el.fireEvent(
'on'+type);
}
}
catch(e){};
}
return {
add: add,
remove: remove,
dispatch: dispatch
};
}();
0
0
标签:JavaScript

Web前端热门文章

    Web前端最新文章

      最新新闻

        热门新闻