我正在开发一个API,我希望能够知道添加或删除对象上的事件侦听器的时间。原因是我发射的一些事件将要求我不断轮询对象以进行更新,如果没有人正在侦听事件,我不想要轮询该对象。 我正在对html5媒体播放器和其他播放器进行轮询以缓冲更新,因此不需要轮询。我也不希望用户必须调用函数来启动轮询添加或删除事件监听器时。
我开发了一个解决方案,在将调用传递给Closure库之前拦截事件监听器的添加,但这是一种非常hacky的做事方式,所以我想找到一个更好的方法。我会在下面发布,但我很想找到一个更好的方法来做到这一点。
感谢任何想法。
答案 0 :(得分:0)
正如我上面所说,我知道这是一种非常黑客的做法,但这是我想出的唯一方法。随意删除sometechie.
命名空间引用和/或在您正在处理的任何项目中使用任何或所有此代码。
/**
* @fileoverview Adds the ability to get events when an event listener is added or removed.
* @author Joshua Dwire
* @requires goog.events
*/
goog.provide('sometechie.eventhack');
goog.provide('sometechie.eventhack.GotListenerEvent');
goog.provide('sometechie.eventhack.LostListenerEvent');
goog.require('goog.events');
/**
* @class Provides a way to get events when an event listener is added or removed
*/
sometechie.eventhack={}
/**
* Generates the type of event that will be fired when a listener of the given type is added.
*
* @example goog.events.listen([src], sometechie.eventhack.generateGotListenerEventType([type]), [listener], [opt_capt], [opt_handler])
*
* @param {string} type Event Type.
* @returns {string} The type of event that will be fired when a listener of the given type is added.
*/
sometechie.eventhack.generateGotListenerEventType=function(type){
return '$sometechie.eventhack.gotlistener@'+type;
}
/**
* Generates the type of event that will be fired when the first listener of the given type is added.
*
* @example goog.events.listen([src], sometechie.eventhack.generateGotFirstListenerEventType([type]), [listener], [opt_capt], [opt_handler])
*
* @param {string} type Event Type.
* @returns {string} The type of event that will be fired when the first listener of the given type is added.
*/
sometechie.eventhack.generateGotFirstListenerEventType=function(type){
return '$sometechie.eventhack.gotfirstlistener@'+type;
}
/**
* Generates the type of event that will be fired when a listener of the given type is removed.
*
* @example goog.events.listen([src], sometechie.eventhack.generateLostListenerEventType([type]), [listener], [opt_capt], [opt_handler])
*
* @param {string} type Event Type.
* @returns {string} The type of event that will be fired when a listener of the given type is removed.
*/
sometechie.eventhack.generateLostListenerEventType=function(type){
return '$sometechie.eventhack.lostlistener@'+type;
}
/**
* Generates the type of event that will be fired when the last listener of the given type is removed.
*
* @example goog.events.listen([src], sometechie.eventhack.generateLostLastListenerEventType([type]), [listener], [opt_capt], [opt_handler])
*
* @param {string} type Event Type.
* @returns {string} The type of event that will be fired when the last listener of the given type is removed.
*/
sometechie.eventhack.generateLostLastListenerEventType=function(type){
return '$sometechie.eventhack.lostlastlistener@'+type;
}
/**
* Object representing a eventhack GotListener event.
*
* @param {string} type Event type.
* @param {Object} target
* @param {string} eventType listener type added.
* @param {boolean} gotFirst If this was the first listener added (there were no listeners before).
* @extends {goog.events.Event}
* @constructor
*/
sometechie.eventhack.GotListenerEvent = function(type, target, eventType, gotFirst) {
goog.base(this, type, target);
this.eventType = eventType;
this.gotFirst = gotFirst;
};
goog.inherits(sometechie.eventhack.GotListenerEvent, goog.events.Event);
/**
* The type of event that was added.
* @type {string}
*/
sometechie.eventhack.GotListenerEvent.prototype.eventType='';
/**
* If this was the first listener added (there were no listeners before).
* @type {boolean}
*/
sometechie.eventhack.GotListenerEvent.prototype.gotFirst=false;
/**
* Object representing a eventhack LostListener event.
*
* @param {string} type Event type.
* @param {Object} target
* @param {string} eventType listener type lost.
* @param {boolean} lostLast If the last listener was removed (there are no listeners anymore).
* @extends {goog.events.Event}
* @constructor
*/
sometechie.eventhack.LostListenerEvent = function(type, target, eventType,lostLast) {
goog.base(this, type, target);
this.eventType = eventType;
this.lostLast = lostLast;
};
goog.inherits(sometechie.eventhack.LostListenerEvent, goog.events.Event);
/**
* The type of event that was removed.
* @type {string}
*/
sometechie.eventhack.LostListenerEvent.prototype.eventType='';
/**
* If the last listener was removed (there are no listeners anymore).
* @type {boolean}
*/
sometechie.eventhack.LostListenerEvent.prototype.lostLast=false;
//Capture adding of event listeners
goog.events.$st_listen_overridden=goog.events.listen;
goog.events.listen=function(src, type, listener, opt_capt, opt_handler){
var eventSrc = /** @type {goog.events.EventTarget} */ src;
var hadListener=false;
try{
if(!goog.isArray(type) && !goog.isNull(type))hadListener=goog.events.hasListener(src,type);
}catch(e){}
var ret = goog.events.$st_listen_overridden.apply(this,arguments);
try{
if(!goog.isArray(type) && !goog.isNull(type)){
var hasListener=goog.events.hasListener(src,type);
var gotFirst=!hadListener&&hasListener;
if(gotFirst){
goog.events.dispatchEvent(eventSrc,
new sometechie.eventhack.GotListenerEvent(
sometechie.eventhack.generateGotFirstListenerEventType(type),
src,type,true));
}
goog.events.dispatchEvent(eventSrc,
new sometechie.eventhack.GotListenerEvent(
sometechie.eventhack.generateGotListenerEventType(type),
src,type,gotFirst));
}
}catch(e){}
return ret;
}
//Capture removing of event listeners
goog.events.$st_unlistenByKey_overridden=goog.events.unlistenByKey;
goog.events.unlistenByKey=function(key){
var src=null,type=null;
try{
if (goog.events.listeners_[key]){
var listener = goog.events.listeners_[key];
if (!listener.removed) {
src = /** @type {goog.events.EventTarget} */ listener.src;
type = listener.type;
}
}
}catch(e){}
var ret = goog.events.$st_unlistenByKey_overridden.apply(this,arguments);
try{
if(src!=null&&type!=null){
var lostLast=!goog.events.hasListener(src,type);
if(lostLast){
goog.events.dispatchEvent(src,
new sometechie.eventhack.LostListenerEvent(
sometechie.eventhack.generateLostLastListenerEventType(type),
src,type,true));
}
goog.events.dispatchEvent(src,
new sometechie.eventhack.LostListenerEvent(
sometechie.eventhack.generateLostListenerEventType(type),
src,type,lostLast));
}
}catch(e){}
return ret;
}