看高程的时候,里面提到自定义事件。其实核心思想都是观察者模式。
当我们addEventListener的时候,dom元素就是主体,回调函数就是观察者。
当我们自定义js事件的时候,event就是主体,回调函数就是观察者。
自定义事件分为两种:
一种是模拟操作的DOM相关事件
一种是用js对象模拟的自定义事件。
模拟dom的事件,一般通过createEvent来构造。
var evt = createEvent('CustomEvent'||'MouseEvent'||'MouseEvent');
evt.initEvent();
evt.dispatchEvent();
可以自定义双击 三击事件。比如
<div id="d1">有本事点我三次</div>
<script type="text/javascript">
var d1 = document.getElementById('d1');
d1.addEventListener('tripleclick',function(event){
alert('我被三击了~');
},false);
var e = new CustomEvent('tripleclick',{'detail':'somemsg'});
var counter = 0;
d1.onclick = function(){
setTimeout(function(){counter=0;},500);
if(++counter==3){
d1.dispatchEvent(e);
}
}
</script>
js的自定义事件,主要用于解耦。也就是我们可以通过继承的方式,将事件对象全部继承过来,在新对象调用自己的某个方法的时候,可以直接fire自定义事件。把事件给抽象出来。
案例可以参考高程提出的。
function EventTarget(){
this.handlers = {};
}
EventTarget.prototype = {
constructor: EventTarget,
addHandler: function(type,handler) {
if(typeof this.handlers[type] == undefined) {
this.handlers[type] = [];
}
this.handlers[type].push(handler);
},
fire: function(event){
if (!event.target) {
event.target = this;
}
if(this.handlers[event.type] instanceof Array) {
let handlers = this.handlers[event.type];
for(let i = 0 , length = handlers.length; i < length; i++) {
handlersi;
}
}
},
removeHandler: function(type,handler) {
if(this.handlers[type] instanceof Array) {
var handlers = this.handlers[type];
for(let i = 0, len = handlers.length; i < len; i++) {
if(handlers[i] == handler) {
break;
}
}
this.handlers.splice(i,1);
}
}
}
function gotest(event) {
console.log('this is'+ event.message + 'test');
}
var target = new EventTarget();
target.addHandler('message',gotest);
target.fire({type:'message',message:'hello world'});
target.removeHandler('message',gotest);
后续直接进行继承就可以使用
function person() {
EventTarget.call(this);
}
person.prototype.say = function(){
this.fire({type;'message',message:'hello world'})
}