事件监听
- 监听多个事件
- 传多个事件类型
<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;//包装函数 ,用来处理ie的this
//字符串切割成数组
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;//包装函数,用来处理ie的this执行问题
}else{
//改变ie的this指向问题
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]);
}
}
}