jQuery防止所有事件冒泡

时间:2013-01-30 11:54:25

标签: events jquery event-bubbling

我正在使用jQuery和它的widget工厂,并使用自定义事件来处理我的应用程序中的事件。

这意味着我的所有事件绑定看起来都很像:

//...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对象添加一个默认的'stop propagation'处理程序,以阻止它们冒泡他们没有特定处理程序的事件。
  3. 或者是否有任何其他良好做法只对那些事件中有趣的元素触发事件,而不是为那些对这些事件不感兴趣的元素触发大量事件。

2 个答案:

答案 0 :(得分:2)

您还可以从事件处理函数返回false以停止传播,这是我通常使用的:

  

从事件处理程序返回false将自动调用event.stopPropagation()和event.preventDefault()。也可以为处理程序传递false值,作为function(){return false;的简写; }。所以,$(" a.disabled")。on("点击",false);将事件处理程序附加到具有类"禁用"的所有链接。这可以防止它们在被点击时被跟踪,并且还可以阻止事件冒泡。

请参阅http://api.jquery.com/on/

答案 1 :(得分: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,因此它不会冒泡到可能也在侦听该事件的其他元素。