2011-09-14 128 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);