0

オブジェクトのイベントリスナーがいつ追加または削除されたかを知りたいAPIを開発しています。その理由は、発生しているイベントの中には、更新のためにオブジェクトを継続的にポーリングする必要があるものがあり、イベントをリッスンしているものがない場合はオブジェクトをポーリングする必要がないためです。更新をバッファリングするためにhtml5メディアプレーヤーと他のプレーヤーをポーリングしているので、ポーリングの必要性を排除することはオプションではありません。また、イベントリスナーを追加または削除するときに、ユーザーがポーリングを開始するための関数を呼び出す必要がないようにします。

呼び出しをClosureLibraryに渡す前に、イベントリスナーの追加をインターセプトするソリューションを開発しましたが、これは非常にハッキーな方法であるため、より良い方法を見つけたいと思います。以下に投稿しますが、これを行うためのより良い方法を見つけたいと思います。

4

1 に答える 1

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;
}
于 2012-10-06T01:43:21.000 に答える