2011-09-14 50 views
2

对给定对象注册的事件进行测试我已经尝试了建议here的答案,其后跟几乎所有类似/重复问题的答案。检查.data('events')根本不起作用,返回undefined我以前有过的对象(立即在那个)注册了一个事件。jQuery;使用.live()

现在,需要注意的是,我实际上使用.live()注册了所述事件,而不是使用.bind()或别名方法。


我刚才读(以前我连发帖的问题)从jQuery的下面上.live()

.live()方法能够影响尚未被添加到元素通过使用事件委托来实现DOM:绑定到祖先元素的处理程序负责在其后代触发的事件。 传递给.live()的处理程序永远不会绑定到元素;相反,.live()将特殊处理程序绑定到DOM树的根目录。在上面的例子中,当单击新元素时...

鉴于这一信息,你会怎么办?(如果有可能的话)检查一个事件是否以“注册”给定物体.live()?有了这个新发现的信息,我猜它会与windowdocument对象开始......


理念更新:如果有一种方法可以挖掘到的.live()的DOM监测能力,或许我可以简单地通过.bind()每当发生变化时重新绑定事件(相同到的.live(),与然而,对于.data('events')检查的支持,这些事件直接绑定。

回答

1

我认为你是对的正确的机架...你可以找到通过调用文档的数据对象绑定到live()处理程序:$.data(document, "events").live

像这样的东西应该是一个很好的起点,以完成你想要的:

function isRegisteredByLive(selector, eventType) 
{ 
    var isRegistered = false; 

    // iterate through all "live" event handlers and check whether the 
    // handler applies to the specified selector and event type 
    $.each($.data(document, "events").live, function(idx, obj) { 
     if (obj.selector === selector && obj.origType === eventType) 
     { 
      isRegistered = true; 
      return false; // break 
     } 
    }); 

    return isRegistered; 
} 

$('a').live('click', function() { alert('test'); }); 

isRegisteredByLive('a', 'click'); // returns true 

你也可以做这样的事情,以确定绑定到特定的DOM元素的所有现场处理:

function getLiveEvents(el) 
{ 
    $.each($.data(document, "events").live, function(idx, obj) { 
     if ($(el).closest(obj.selector).length > 0) 
     { 
      console.log(obj.handler); 
     } 
    }); 
} 
+0

太好了!谢谢@ RocccoC5 - 像魅力一样工作,我只需要在第一个解决方案(*'obj [0] .selector')中为'obj'添加一个偏移量,因为它返回一个单元素数组* * – Dan

+0

@Bracketworks - 很高兴听到。不知道为什么你需要在'obj'上指定索引。调用'each()'应该遍历'$ .data(document,“events”),live'数组中的每个对象,并将对象的索引作为'idx'参数传递给函数,和实际的对象作为'obj'参数。看看这个:http://jsfiddle.net/Xu3Yn/1/ – RoccoC5

0

我写了一个jQuery函数如果一个元素的事件被注册(元素和生活如果必要的话),检查

代码:

(function ($) { 
    $.fn.eventRegistered = function (eventName, includeLiveEvents) { 
     if (includeLiveEvents != true) 
      includeLiveEvents = false; 

     if (this == null || this.length == 0) 
      return false; 

     for (var i = 0; i < this.length; ++i) { 
      var events = $(this[0]).data("events"); 

      if (events == null) 
       continue; 

      if (events[eventName] != null) 
       return true; 
     } 

     if (includeLiveEvents) { 
      var liveEvents = $.data(document, "events").live; 

      for (var i = 0; i < liveEvents.length; ++i) { 
       if (liveEvents[i].selector == this.selector && liveEvents[i].origType == eventName) 
        return true; 
      } 
     } 

     return false; 
    }; 
})(jQuery); 

实施例一用法: VAR isRegistered = $( '的className。')。eventRegistered( “点击”); //将返回true,如果点击注册了至少一个具有类className的元素

var isRegistered = $('.className').eventRegistered("change", true); // will return true if change is registered on at least one element that has a class className or using live function 

要小心。这个函数打破了链条,所以你不能用它喜欢:

$('.className').eventRegistered("change").change(function() { 
    // ... 
}); 
1

我最近更新的jQuery到最新版本(1.7.1),我意识到,我不能使用

var liveEvents = $.data(document, "events").live; 

,因为住的是不那里了。相反,你检查一下,变化等。以下是我此之前发布的代码的更新版本(与旧的jQuery版本使用的是另一种发布此页):

(function ($) { 
    $.fn.eventRegistered = function (eventName, includeLiveEvents) { 
     if (includeLiveEvents != true) 
      includeLiveEvents = false; 

     if (this == null || this.length == 0) 
      return false; 

     for (var i = 0; i < this.length; ++i) { 
      var events = $(this[0]).data("events"); 

      if (events == null) 
       continue; 

      if (events[eventName] != null) 
       return true; 
     } 

     if (includeLiveEvents) { 
      return this.eventRegisteredLive(eventName); 
     } 

     return false; 
    }; 
})(jQuery); 

(function ($) { 
    $.fn.eventRegisteredLive = function (eventName) { 
     var liveEvents = $.data(document, "events")[eventName]; 

     if (!liveEvents) 
     { 
      return false; 
     } 

     for (var i = 0; i < liveEvents.length; ++i) { 
      if (liveEvents[i].selector == this.selector) 
       return true; 
     } 
     return false; 
    }; 
})(jQuery);