zoukankan      html  css  js  c++  java
  • 事件模块---自定义事件和自动触发事件

    原理请看:http://www.cnblogs.com/snandy/archive/2011/04/08/2007976.html

    直接上自己一步步根据抄袭来的代码的js,自己亲手写了一遍:

    var Event = 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;){
                //调用callBck 返回true的话 从头开始遍历,否则继续遍历
                callback(i, ary[i]) ? i=0 : i++;
            }
        };
        //解除绑定事件
         function _remove(el, type){
             //获取已经绑定的事件集合
            var handler = el.listeners[type]['_handler_'];
            console.log(el.listeners[type]);
            el.removeEventListener ?
                el.removeEventListener(type, handler, false) :
                el.detachEvent('on'+type, handler);
            //删除事件绑定事件函数
            delete el.listeners[type];
            //如果为空,那么删除元素上绑定的属性
            if(_isEmptyObj(el.listeners)){
                delete el.listeners;
            }
        }
    
        //移除某一类型的事件
        function removeEvent(ele,type,fn){
                //如果ele没有添加的属性,则事件绑定不存在
                 if(!ele.listeners) return;
                 //获取一类事件的函数
                  var listeners = ele.listeners && ele.listeners[type];
    
                  if(listeners){
                          //遍历listeners
                          _each(listeners, function(i, f){
                              //如果 遍历到的函数与要移除的函数的函数名相同时,截取这个函数
                            if(f==fn){
                                return listeners.splice(i, 1);
                            }
                        });
                          //当绑定事件全被干掉了,就解除绑定的["__handle__"]
                        if(listeners.length == 0){
                             _remove(ele,type);
                        }
                  }
        }
        //添加自定义事件
        function addEvent(ele,type,fn){
    
            //给元素加上一个属性,如果存在就等于存在的对象,不存在则为空对象
            ele.listeners = ele.listeners || {};
            //存储独享的key值为type,存在的话直接就为已有的数组,否则为空数组
            var listeners = ele.listeners[type] = (ele.listeners[type] || []);
            //把这一类事件的回调函数存储起来
            listeners.push(fn);
            //每一个函数的listeners,目的是创造一个函数,使addEventListener和attachEvent的内部this都指向元素本身
            if(!listeners["__handle__"]){
                listeners["__handle__"] = function (ev){
                    var ev = ev || window.event; //兼容事件对象
                    
                    for(var i=0,fn;fn=listeners[i++];){
                        //调用一类事件所存储的回调函数,handle被调用时,依次调用;
                        fn.call(ele,ev);
                    };    
                };
    
                ele.addEventListener ? ele.addEventListener(type,listeners["__handle__"],false) :
                                       ele.attachEvent("on"+type,listeners["__handle__"]);
            };
        };
        //自动触发事件
        function dispatch(ele,type){
            try{
                if(ele.dispatchEvent){  //标准浏览器
    
                    var evt = document.createEvent("Event");
                        evt.initEvent(type,true,true);
                        ele.dispatchEvent(evt);
                }else{
                    ele.fireEvent("on"+type);
                }
            }catch(e){};
                
        }
    
        return {
            addEvent:addEvent,
            dispatch:dispatch,
            removeEvent:removeEvent
        }
    
    
    
    
    }();

    这也是一道面试题!

  • 相关阅读:
    [导入]微软的XP和Server2003在双核CPU上有缺陷
    [导入]可怜的软件开发
    [CZoneSoft]在Firefox里播放wmv流媒体视频
    [导入]直接用IL改写别人的程序
    [导入]清除3721的中文上网插件CNS
    [导入]完成可脚本调用的视频录制控件
    垃圾短信投诉的地方和方法
    [导入]不需要服务器端的在线录制视频
    [导入]各银行跨行提款收费比较
    [导入]电热水器选购
  • 原文地址:https://www.cnblogs.com/floatboy/p/event.html
Copyright © 2011-2022 走看看