您的位置:首页 > Web前端 > JavaScript

使用原生JavaScript实现的EventEmitter

2015-08-08 22:46 726 查看
和Nodejs 中EventEmitter功能类似.适合浏览器自定义事件类.新添加了可以定制事件促发次数的功能.

详细见
https://github.com/webery/ajax/tree/master
包括了源代码和测试代码.未经过严格测试,暂时为第一个版本.还有很多优化的地方,现在只是一个参考.

使用方法

前端测试文件:emit.ejs

<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<script type="text/javascript" src="/javascripts/eventemitter.js"></script>
</head>
<body>
<input type="button" id="submit" value="click">
</body>
<script type="text/javascript">
document.getElementById('submit').onclick = function() {
/*
var emit = new EventEmitter();

emit.on('click', function() {
console.log('clcik');
}, 2);
emit.trigger('click');
emit.trigger('click');
emit.trigger('click');
*/
var Target = function(){};
EventEmitter.inherit(Target);
var test = new Target();
test.on('click', function() {
console.log('clcik');
}, 2);
test.trigger('click');
test.trigger('click');

};
</script>
</html>


源代码:eventemitter.js

/**
author:weber yang
2015.7.31
浏览器端模拟EventEmitter的实现,拓展了部分功能,添加了定制实践促发的次数的功能,
使用方式和其他的EventEmiiter类似。
**/
;(function (window, undefined) {
'use strict';
/*构造函数*/
var EventEmitter = function() {
this.events = {};//保存事务,存储结构为{'eventName1':[{listener:function触发的函数, time:触发的次数}], 'eventName2':[],}
};

EventEmitter.prototype.once = function(evt, listener) {
return this.addListener(evt, listener, 0);
};
/*获取所有的事务*/
EventEmitter.prototype.getEvents = function() {
return this.events || (this.events = {});
}
/*获取某个实践的所有触发函数*/
EventEmitter.prototype.getListeners = function(evt) {
var events = this.getEvents();
return events[evt] || (events[evt] = []);
};
/**
注册实践触发函数
evet:事件名称
listener:事件监听函数
time:可选,选择可以触发的次数,-1表示无数次,默认为-1
**/
EventEmitter.prototype.on = function(evt, listener, time) {
time = typeof(time) == 'number' ? time : -1;
time = time >= -1 ? time : -1;
var listeners = this.getListeners(evt);
var listenerWrapper = {
listener:listener,
time:time,
};
listeners.push(listenerWrapper);

return this;
};
/*addListener 和on 同义 */
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
/*移除事件的所有监听函数*/
EventEmitter.prototype.off = function(evt) {
var events = this.getEvents();
events[evt] = [];
};
EventEmitter.prototype.removeEvent = EventEmitter.prototype.off;

/**
会删除同一事件中的所有listener
**/
EventEmitter.prototype.removeListener = function(evt, listener) {
var listeners = this.getListeners(evt);
for(var i=0; i<listeners.length; i++) {
if(listeners[i].listener == listener) {
delete listeners[i];
}
}
};
/**
触发事件
**/
EventEmitter.prototype.trigger = function(evt, args) {
var listeners = this.getListeners(evt);
for(var i=0; i<listeners.length; i++){
var listener = listeners[i];
if(listener.time != -1) {
listener.time--;
}
if (listener.time == 0) {
this.removeListener(evt, listener.listener);//可以同步或异步执行
}
listener.listener.apply(this, args || []);
}
};
EventEmitter.prototype.fire = EventEmitter.prototype.trigger;
/**
触发事件
**/
EventEmitter.prototype.emit = function(evt) {
var args = Array.prototype.slice.call(arguments, 1);
return this.trigger(evt, args);
};

EventEmitter.inherit = function(target) {

if(typeof(target.prototype) == 'undefined') {
throw 'target:' + target + 'must have prototype';
}
var souPto = EventEmitter.prototype;
var tarPto = target.prototype;
for(var key in souPto) {
tarPto[key] = souPto[key];
}
return target;
};

window.EventEmitter = EventEmitter;

})(window);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: