我们先来看一下正常的事件绑定形式:
doucment.getElementById("btn").addEventLisnter("click",function(event){ // your processing })
我们可以看出正常事件绑定需要四个组成部分:
1 获取的元素(Element的子类)
2 事件绑定函数 (addEventLisnter)
3 事件类型 (click)
4 事件触发的回调函数 (function(event){})
其原理是:所有的Element元素实现了EventTarget接口,在该接口中定义了三个方法,
EventTarget.addEventListener() EventTarget.removeEventListener() EventTarget.dispatchEvent()
所有实现了EventTarget的元素类型,均可以调用以上三个方法。在浏览器查看Element对象原型链继承时候也可以看到三个方法:
console.log(Element.prototype)
所以实现一个自定义事件也要考虑以上原理:
// 构造函数+原型模式创建对象 function MyEventTarget(){ /*handlers = { "message":[func1,func2,func3], "info":[func4,func5,func6] ...... }*/ this.handlers = {}; }
// 相应类型的事件添加上不同的处理方法 MyEventTarget.prototype.addEvent= function(type, handler){ if(typeof this.handlers[type] === 'undefined'){ this.handlers[type] = []; } this.handlers[type].push(handler); }
// 移出相应类型事件所对应的方法 MyEventTarget.prototype.removeEvent= function(type, handler){ if(this.handlers[type] instanceof Array){ var handers = this.handlers[type]; for(var i=0, len=handers.length; i< len;i++) { if(handers[i] === handler){ break; } } handers.splice(i,1); } }
MyEventTarget.prototype.fire = function(event){ if(!event.target){ event.target = this; } // 如果是数组 if(this.handlers[event.type] instanceof Array){ var handlers = this.handlers[event.type]; for(var i=0, len=handlers.length; i< len; i++){ // 调用每一个事件处理函数 handlers[i](event); } } }
// 自定义时间处理函数 function handler1(event){ alert("handler1"+ event.say); }
// 创建目标对象 var target = new MyEventTarget(); // 给目标对象添加事件以及事件处理函数 target.addEvent("message",handler1); // 把事件和事件处理函数相关联起来 事件 target.fire({type:"message",say:"asdd"});
我们现在给自定义事件对象添加子类:(好比给Element实现一个HTMLElement,而HTEMLElement上也具备Element上的事件方法)
function object(o){ function F(){} F.prototype = o; return new F(); }
function inheritPrototype(subType, superType){ var prototype = object(superType.prototype); prototype.constructor = subType; subType.prototype = prototype; }
function Person(name, age){ EventTarget.call(this); //借用构造函数 this.name = name; this.age = age; } inheritPrototype(Person,MyEventTarget); // 触发事件方法 Person.prototype.say = function(message){ this.fire({type: "message", message: message}); }; // 自定义事件 function handleMessage(event){ alert(event.target.name + " says: " + event.message); } var person = new Person("Nicholas", 29); //监听 person.addEvent("message", handleMessage); //触发 person.say("Hi there.");
参考《Js高级程序设计》P616
参考:http://devdocs.io/dom/eventtarget(有一种新的实现方式)
https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget
-----------------------------------------------------
转载请注明来源此处
原地址:#
发表