• 技术文章 >web前端 >js教程

    Javascript处理DOM元素事件实现代码_javascript技巧

    2016-05-16 17:53:22原创350
    DOM元素都有一些标准事件,一般使用时只要使用onclick=function的方式就可以了,但是当需要为DOM元素添加多个事件,删除事件,或在用Javascript封装控件的时候,为封装的控件添加自定义事件的时候,onclick=function的方式就不够用了,但是浏览器有addEventListener和attachEvent方法可供调用,从而模拟出类似于C#中的事件委托的事件触发机制!
    复制代码 代码如下:

    /*
    * 功能:事件处理
    * Author:LQB
    * 时间:2009-1-4
    * #include JCore.js
    */
    var JEvents = function(){
    this.events={};
    this.addEvent = function(o){//添加事件
    if(typeof o == 'string'){/*strArg1,strArg2……的方式传递参数*/
    for(var i = 0, a = arguments, v; v = a[i]; i++){
    v = v.toString().toLowerCase();
    var enFX = v.indexOf("on")==0 ? v.substr(2) : v;
    if(!this.events[enFX]){
    this.events[enFX] = true;
    }
    }
    }else{
    JCore.apply(this.events, o,false);
    }
    };
    this.addListener = function(eventName,fn,scope/*,Args……*/){//为事件添加处理方法
    if(typeof(eventName)!="string"|| eventName.lenght==0)return;
    if(typeof(fn)!="function")return;
    eventName = eventName.toString().toLowerCase();
    var enFX = eventName.indexOf("on")==0 ? eventName.substr(2) : eventName;
    if(!this.events[enFX]){
    throw "Error! Event /"" + eName + "//m.sbmmt.com/m/" doesnt exist."
    }
    var sp = scope||window;
    var callArgs = Array.prototype.slice.call(arguments, 3);//从第4个参数开始
    callArgs = typeof(callArgs)!="undefined"?callArgs:[];
    var delegate = fn.createDelegate(callArgs,sp);//JCore支持
    //为fn方法创建标记,在删除事件时使用
    if(!fn.uid) {
    var time = new Date();
    fn.uid= ""+time.getMinutes()+time.getSeconds()+time.getMilliseconds();
    }
    //标记委托,在删除事件绑定时使用
    delegate.uid = getCacheAttName(enFX,fn.uid);
    if(typeof(this.events[enFX])!="object")
    this.events[enFX]=[];
    this.events[enFX].push(delegate);//把方法添加到事件列表中
    };
    this.removeListener = function(eventName,fn){//移除事件绑定
    if(eventName && fn){
    eventName = eventName.toString().toLowerCase();
    var enFX = eventName.indexOf("on")==0?eventName.substr(2):eventName;
    var AttName = getCacheAttName(enFX,fn.uid);
    if(typeof(this.events[enFX])=="object"){//存在这个事件
    var functions = this.events[enFX];
    for(i=0;iif(functions[i].uid===AttName){//找到,删除
    this.events[enFX].remove(functions[i]);
    break;
    }
    }
    }
    }
    }
    this.fireEvent = function(eName,eventArg){//触发事件
    eName = eName.toString().toLowerCase();
    var enFX = eName.indexOf("on")==0 ? eName.substr(2) : eName;
    var Arg = new Array();
    if(typeof(eventArg)!="undefined"){
    if(typeof(eventArg)=="array") Arg=eventArg;
    else Arg.push(eventArg);
    }
    if(typeof(this.events[enFX])=="object"){//存在此事件,同时添加了事件处理方法
    var functions = this.events[enFX];
    for(i=0;ifunctions[i].apply(window,Arg);
    }
    }
    }
    /*---------------------------------------私有方法--------------------------------------*/
    var getCacheAttName = function(eventName,fnuid){
    return "handle-"+eventName+"-"+fnuid;
    }
    }
    /*------------------------------------------------------以下是静态方法,用于处理DOM element的事件-----------------------------------------*/
    var JEventsExtendMethod = {
    cache : {//时间处理缓存,用于标记各个事件处理方法,在删除事件时使用
    eventCache : {},
    setCache : function(el,Name,value){
    if(typeof(this.eventCache[el])!="object"){
    this.eventCache[el]={length :1};
    }
    this.eventCache[el][Name]=value;
    this.eventCache[el].length++;
    },
    getCache : function(el,Name){
    if(typeof(this.eventCache[el]) =="object")
    return this.eventCache[el][Name];
    else
    return null;
    },
    removeCache : function(el,Name){
    if(typeof(this.eventCache[el]) =="object"){
    delete this.eventCache[el][Name];//删除属性
    this.eventCache[el].length--;
    }
    if(this.eventCache[el] && this.eventCache[el].length ==1)//清除
    delete this.eventCache[el];
    }
    },
    getCacheAttName : function(eventName,fnuid){
    return "handle-"+eventName+"-"+fnuid;
    },
    bind : function(el,eventName,fn,scope/*,Args……*/){//为elment添加事件处理方法
    if(typeof(el)=="undefined"||el==null)return;
    if(typeof(eventName)!="string"|| eventName.lenght==0)return;
    if(typeof(fn)!="function")return;
    var indexOfon = eventName.toString().toLowerCase().indexOf("on");
    var enIE = indexOfon==0?eventName:"on"+eventName;
    var enFX = indexOfon==0?eventName.substr(2):eventName;
    var sp = scope||window;
    var callArgs = Array.prototype.slice.call(arguments, 4);//从第5个参数开始
    callArgs = typeof(callArgs)!="undefined"?callArgs:[];
    var delegate = fn.createDelegate(callArgs,sp);//JCore支持
    if (el.addEventListener){//Mozilla系列,按队列顺序执行
    el.addEventListener(enFX, delegate, false);//第三个参数与触发方式相关
    } else if (el.attachEvent){//非Mozilla系列,按堆栈顺序执行(后加的事件先执行)
    el.attachEvent(enIE, delegate);
    }
    //为fn方法创建标记,在删除事件时使用
    if(!fn.uid) {
    var time = new Date();
    fn.uid= ""+time.getMinutes()+time.getSeconds()+time.getMilliseconds();
    }
    if(!el.id){
    el.id = JCore.id(el,null);
    }
    //标记委托,在删除事件绑定时使用
    var AttName = this.getCacheAttName(enFX,fn.uid);
    this.cache.setCache(el.id,AttName,delegate);
    },
    unbind : function(el,eventName,fn){//为elment解除事件绑定
    if(typeof(el)=="undefined"||el==null)return;
    var indexOfon = eventName.toString().toLowerCase().indexOf("on");
    var enIE = indexOfon==0?eventName:"on"+eventName;
    var enFX = indexOfon==0?eventName.substr(2):eventName;
    var AttName = this.getCacheAttName(enFX,fn.uid);
    var delegate = this.cache.getCache(el.id,AttName);
    if(delegate){
    if (el.removeEventListener){//Mozilla系列
    el.removeEventListener(enFX, delegate, false);
    } else if (el.detachEvent){//非Mozilla系列
    el.detachEvent(enIE, delegate);
    }
    }
    //删除事件缓存
    this.cache.removeCache(el.id,AttName);
    }
    }
    JCore.apply(JEvents,JEventsExtendMethod);
    /*--------------------------------对event的参数包装---------------------------------*/
    var JEventWrap = function(event){
    this.xtype="EventWrap";
    this.data=null;
    this.srcElement = null; //发生事件的文档元素
    this.button = null; //[FX:0-左键,1-中间键,2-右键][IE:1-左键,2-右键,4-中键](仅对onmousedown, onmouseup,onmousemove有效)
    this.type = null;
    this.clientX = 0; //鼠标指针相对客户区或浏览器窗口的X坐标(标准属性)
    this.clientY = 0; //鼠标指针相对客户区或浏览器窗口的Y坐标(标准属性)
    this.offsetX = 0; //鼠标指针相对于源元素的X坐标(兼容属性)(IE)
    this.offsetY = 0; //鼠标指针相对于源元素的Y坐标(兼容属性)(IE)
    this.screenX = 0; //鼠标指针相对于用户显示器的左上角X坐标(兼容属性)(FX)
    this.screenY = 0; //鼠标指针相对于用户显示器的左上角Y坐标(兼容属性)(FX)
    this.altKey = false; //是否Alt键
    this.ctrlKey = false; //是否Ctrl键,
    this.shitfKey = false; //是否Shift键
    this.keyCode = 0;
    this.originaEvent = null; //未包装的原始事件对象
    /*----构造-----*/
    if(event){
    if(event.srcElement){//IE
    this.srcElement = event.srcElement;
    this.offsetX = event.offsetX;
    this.offsetY = event.offsetY;
    this.button = event.button;
    }
    else{
    this.srcElement = event.target;
    this.offsetX = event.clientX - event.target.offsetLeft;
    this.offsetY = event.clientY - event.target.offsetTop;
    }
    this.type = event.type;
    this.altKey = event.altKey;
    this.ctrlKey = event.ctrlKey;
    this.shitfKey = event.shitfKey;
    this.clientX = event.clientX;
    this.clientY = event.clientY;
    this.screenX = event.screenX;
    this.screenY = event.screenY;
    this.keyCode = event.keyCode;
    this.originaEvent = event;
    }
    }

    其中JCore.js文件见上一篇日志:面向对象Javascript核心支持代码
    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:DOM元素事件
    上一篇:Javascript 面向对象(三)接口代码_js面向对象 下一篇:通过js动态操作table(新增,删除相关列信息)_javascript技巧
    Web大前端开发直播班

    相关文章推荐

    • Angular利用service实现自定义服务(notification)• 带你了解JavaScript中的键盘、鼠标事件• 聊聊怎么利用Angular+Jenkins展示构建版本• 手把手带你使用Node.js和adb开发一个手机备份小工具• 你能搞懂JS的this指向问题吗?看看这篇文章

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网