0

ウィジェット ファクトリで jQuery を使用し、カスタム イベントを使用してアプリケーションのイベントを処理しています。

これは、すべてのイベント バインディングが次のようになることを意味します。

//...in the widget factory code

$(this.element).addClass('customEventClass');
$(this.element).bind('mysite.loadNextPage', $.proxy(this, 'loadNextPage');

イベントは次のようにしてトリガーされます。

$('.customEventClass').trigger('mysite.loadNextPage');

イベントは、それらを受け取る必要がある要素に直接バインドされるため、これらのカスタム イベントを DOM でバブルアップさせる必要はありません。イベントハンドラーコードでこれを行うことで、イベントがバブルアップしたかどうかを確認できることがわかっています。

if (event.target != event.currentTarget) {
    event.stopPropagation();
    event.preventDefault();
    return;
}

しかし、現時点では、カスタム イベントをリッスンしている要素のほとんどに「mysite.loadNextPage」のハンドラーが登録されていないため、51 のイベントが生成され、そのうち 1 つだけが実際に何かを行います。次のいずれかの方法はありますか:

  1. これらのイベントをまったくバブルしないように jQuery に指示するか、
  2. クラス「customEventClass」を持つすべての DOM オブジェクトにデフォルトの「伝播停止」ハンドラーを追加して、特定のハンドラーを持たないイベントのバブルアップを停止します。

または、それらのイベントに関心のない要素に対して多くのイベントをトリガーするのではなく、それらのイベントに関心のある要素でのみイベントをトリガーするための他の良い方法はありますか?

4

2 に答える 2

1

jQueryをそのまま使用するのは良い方法ではないようですが、これを可能にする新しい関数を作成するのは非常に簡単です。

最初に、イベントのバブリングを停止する新しい関数を作成しました(また、イベントをログに記録します)。

function    eventWrapper(event){

    var logString = 'Event called: ' + event.type + ":" + event.namespace;

    if (jQuery.isFunction(this.log) == true) {
        this.log(logString);
    }
    else if (jQuery.isFunction(Logger.log) == true) {
        Logger.log(logString);
    }
    else{
        console.log(logString);
    }

    event.stopPropagation();
}

そして今、jQueryに追加された新しい関数。

// A global GUID counter for objects
guidWrapper: 1,

proxyWrapper: function(wrappedFn, fn, context, wrapFn ) {

    var args, proxy, tmp;

    if ( typeof context === "string" ) {
        tmp = fn[ context ];
        context = fn;
        fn = tmp;
    }

    // Quick check to determine if target is callable, in the spec
    // this throws a TypeError, but we will just return undefined.
    if ( !jQuery.isFunction( fn ) ) {
        return undefined;
    }

    // Simulated bind
    args = core_slice.call( arguments, 3 );
    proxy = function() {
        wrappedFn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
        return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
    };

    // Set the guid of unique handler to the same of original handler, so it can be removed
    proxy.guid = fn.guid = fn.guid || jQuery.guid++;

    return proxy;
},

そして、次のように関数をバインドする代わりに:

$(this.element).bind('click', $.proxy(this.click, this));

代わりに、このようにバインドします。

$(this.element).bind('click', $.proxyWrapper(eventWrapper, this.click, this));

これは、イベントがトリガーされると、そのイベントをリッスンしている最初の要素がイベントでevent.stopPropagationを呼び出すため、そのイベントをリッスンしている可能性のある他の要素にバブルアップしないことを意味します。

于 2013-02-06T02:47:25.420 に答える