javascript--38--完整版事件封装

事件监听

  1. 监听多个事件
  2. 传多个事件类型
<body>
  <div id="box"></div>
<script>

    eventBind(box,"click",function (event) {
        console.log("1");
    },false);
    eventBind(box,"click",function (event) {
        console.log("2");
    },false);
    eventBind(box,"dblclick",function (event) {
        console.log("0");
        eventUnbind(box,"click",false);
    },false);
    /*ele 元素节点
    * event事件类型
    * Handel 处理事件函数
    * capture 是否为捕获
    * */
    function eventBind(ele,event,handle,capture) {
        //包装函数做处理  用于取消函数和this指向问题
        ele["event"+event] = handle;

        //先判断浏览器是否为主流浏览器
        if (ele.addEventListener){
            ele.addEventListener(event,ele["event"+event],capture);
        }else if (ele.attachEvent){
            ele["event"+event] =function(){
                handle.call(ele,window.event)
            };
            ele.attachEvent("on"+event,ele["event"+event]);
        }
    }
    //注销事件
    function eventUnbind(ele,event,capture) {
        if (ele.removeEventListener){
            ele.removeEventListener(event,ele["event"+event],capture);
        }else if (ele.detachEvent){
            ele.detachEvent("on"+event,ele["event"+event]);
        }
    }
</script>

这样双击只能取消最后一个事件

所以一个点击可以触发多个函数 一个对象可以有多个事件 对象加数组

box._event ={
    click:[],
    mousedown:[],
}
 eventBind(box,"mouseover,mouseout,click",function (e) {//相当于滚轮事件的兼容
        e=e||window.event;
       console.log(e.type);
    });
    function eventBind(ele,event,fn,blooe) {
        //包装函数做处理  用于取消函数和this指向问题
        var handlerFn =fn;//包装函数 ,用来处理iethis


        //字符串切割成数组
        event=event.split(",");
        console.log(event);
       for (var ev=0,evL=event.length;ev<evL;ev++){
            //先判断浏览器是否为主流浏览器
            if (ele.addEventListener){
                ele.addEventListener(event[ev],handlerFn,blooe);
            }else if (ele.attachEvent){
                handlerFn=function(){
                    fn.call(ele,window.event);//ie低版本没有bind方法
                }
                ele.attachEvent("on"+event[ev],handlerFn);
            }
            var eventList =(ele._event||(ele._event={}))[event[ev]]||(ele._event[event[ev]]=[]);
            // ele._event[event].push(handlerFn);
            eventList.push(handlerFn);
            //把处理过的函数返回出去
        }

        //保存函数到队列
        // if (!ele._event){
        //     ele._event={};//第一次进来先要设置对象的属性为一个{}
        // }
        // if (!ele._event[event]){
        //     ele._event[event]=[];//事件类型为数组
        // }

        //简洁写法  每次赋完值等于等号的右边

        return handlerFn;
    }
    //注销事件
    function eventUnbind(ele,event,capture) {
        if (ele.removeEventListener){
            ele.removeEventListener(event,ele["event"+event],capture);
        }else if (ele.detachEvent){
            ele.detachEvent("on"+event,ele["event"+event]);
        }
    }

长用于 input失去焦点时候触发 改变时候触发;滚轮事件的兼容绑定

<input type="text" id="text">
 eventBind(text ,"blur,change",function () {
        console.log(this)
    })
 eventBind(box,"DOMMouseScroll,mousewheel",function (e) {
        
    })

完整版事件封装监听

//一次性事件
function oneEvent(ele,eventType,fn,blooe){

	var handlerFn = eventBind(ele,eventType,function(e){

		e = e || window.event;
		//console.log('一次性事件里的',this);//节点
		//fn.call(this,e);//传进来的处理事件函数
		fn.call(this,e);//函数自执行而不是 事件函数触发

		eventUnBind(ele,e.type,handlerFn,blooe);
	},blooe);
}

//注册监听方法
function eventBind(ele,eventType,fn,blooe){

	//是否为ie
	if(ele.addEventListener){

		var handlerFn = fn;//包装函数,用来处理iethis执行问题
	}else{

		//改变iethis指向问题
		var handlerFn = function(){

				fn.call(ele);//ie低版本没有bind方法
			};
	}

	//字符串切割成数组
	eventType = eventType.split(',');

	//遍历事件类型
	for(var ev = 0,evL = eventType.length;ev < evL;ev++){

		//先判断是否为主流浏览器
		if(ele.addEventListener){

			ele.addEventListener(eventType[ev],handlerFn,blooe);
		}else{//ie浏览器

			ele.attachEvent('on'+eventType[ev],handlerFn);//ie只有冒泡,没有捕获
		}

		//保存函数到队列

		/*//默认第一次进来时ele._event要默认等于一个空json数据{}
		if(!ele._event){
			
			ele._event = {};
		}
		//事件类型第一次进来,同样的要等于一个空数组[]
		if(!ele._event[eventType]){

			ele._event[eventType] = [];
		}
		*/

		//每次赋值完值都会返回你赋值的数据
		var eventList = (ele._event || (ele._event = {}))[eventType[ev]] || (ele._event[eventType[ev]] = []);
		
		//在节点上的_event下面事件类型(事件类型是一个数组)push添加一个事件处理函数
		eventList.push(handlerFn);
	}

	//最后把处理过的事件处理函数返回出去
	return handlerFn;
}

//事件注销
function eventUnBind(ele,eventType,fn,blooe){

	//字符串切割成数组
	eventType = eventType.split(',');

	//遍历事件类型
	for(var ev = 0,evL = eventType.length;ev < evL;ev++){

		if(!ele._event || !ele._event[eventType[ev]]){

			//return;//函数里return 后面的代码不会再执行
			continue;//如果不存在就跳过当前这次
		}

		var _key = null,//用于保存事件队列的下标
			eventList = ele._event[eventType[ev]];//事件队列

		//fn是一个函数,指定函数进行注销
		if(typeof fn == 'function'){

			//如果是一个函数
			for(var f = 0,fL = eventList.length;f < fL;f++){

				//在事件队列找到想删除的fn
				if(fn == eventList[f]){

					_key = f;//key值等于当前下标
					break;//找到之后跳出循环
				}
			}
		}else{//默认注销最后一个

			_key = eventList.length - 1;
		}

		//如果找不到就直接return
		if(_key === null){return;}
		
		//默认注销最后一次事件函数
		if (ele.removeEventListener) {//主流浏览器

			ele.removeEventListener(eventType[ev],eventList.splice(_key, 1)[0],blooe);
		}else{//ie浏览器

			ele.detachEvent('on'+eventType[ev],eventList.splice(_key, 1)[0]);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/lxhby520/article/details/80909978