2013-05-20 38 views
1

我的目標是防止所有的點擊事件(點擊時在HTML中隱藏/顯示元素),除非滿足某個條件(用戶在輸入元素中有特定的詞)。jQuery stopPropagation被忽略

所以我試圖將該邏輯添加到文檔或「html」的點擊處理程序,但其他元素的點擊處理程序首先因爲氣泡而被解僱。

所以我嘗試將該邏輯附加到「*」,現在該單擊處理程序首先觸發 - 但將其傳播到其他元素,忽略stopPropagation,preventDefault並返回false。

$(document).ready(function(){  
    $("*").click(function(event){ 
    if ($("#user").val() !== "admin"){ 
     console.log("1"); 
     event.stopPropagation(); 
     event.preventDefault(); 
     return false; 
    } 
    }); 
    $("#user").click(function(event){ 
    console.log("2"); 
    // do something 
    }); 
}); 
  1. 爲什麼「2」被寫入「1」後的控制檯時,不應該有,因爲將返回false/stopPropagation的任何進一步傳播?
  2. 我該如何使用jQuery實現我的目標?

謝謝!

+13

'$(「*」)。click'我的心剛跳過一拍。 –

+0

如果你阻止所有的點擊事件,用戶如何點擊'user'元素,以便他可以輸入'admin'? – Barmar

+0

@Barmar,重點始於用戶,我不會讓它去任何其他地方 – yair

回答

1
  1. stopPropagation()阻止事件傳播的任何進一步父類樹。但是,它不會阻止當前的剩餘事件處理程序被觸發。

    要做到這(防止進一步傳播防止被解僱當前元素上的任何進一步的事件處理程序),你需要調用stopImmediatePropagation()(相反,不以及)。

  2. 附加以這種方式的事件處理程序的每個元素,並調用stopImmediatePropagation()(以及preventDefault()防止所有點擊從具有效果; 提供沒有事件處理程序綁定之前(因爲處理程序按順序執行;您不能撤消已經觸發的處理程序)。

    但是,這並不是不錯雖然找到,枚舉和附加處理程序到每個元素是非常昂貴的。

    爲了讓更好,你的選擇要麼是:

    1. 附上click事件document,根本preventDefault()和犧牲stopImmediatePropagation()

    2. 檢查每個事件處理程序中的狀態#user;你可以通過滾動你自己的包裝函數來緩解這種痛苦;

      function checkUserState(then) { 
          return function() { 
           if ($("#user").val() !== "admin") { 
            then.apply(this, arguments); 
           } 
          }; 
      }; 
      

      ...像這樣使用;

      $("#user").click(checkUserState(function(event){ 
          console.log("2"); 
      })); 
      

    正如在評論中指出,我有意避免使用事件代表團的建議,因爲雖然可以只連接一個事件處理程序,而不是n,它不會讓你的事件stopPropagation()

+0

'$(document).on(「click」,「*」,...)'將是一個更好的方式來實現這一點,因爲它不必找到並將處理程序綁定到每個元素。 – Barmar

+0

@Barmar:雖然這不會讓你'stopPropagation',因爲事件已經冒泡到'document'中。 – Matt

+0

謝謝!我不明白第一個更好的選擇,我認爲我們建立附加一個點擊處理程序的文件不會幫助,因爲它是最後被解僱? – yair