2010-08-16 65 views
3

HTML:jQuery的命名空間不起泡,其自定義事件

<div class="parent"> 
    <div class="child1" > 
    </div> 
    <div class="child2"> 
    </div> 
</div> 

<a class="btn1">customClick.btn1</a> 
<a class="btn2">customClick.btn2</a> 

的JavaScript:

jQuery('div.child1') 
    .bind('customClick.btn1', function() { 
     alert('child1 reacted to customClick.btn1'); 
    }); 


jQuery('div.child2') 
    .bind('customClick.btn2', function() { 
     alert('child2 reacted to customClick.btn2'); 
    }); 

jQuery('div.parent') 
    .bind('customClick.btn1', function (e) { 
     alert('parent reacted to customClick.btn1'); 
    }) 
    .bind('customClick.btn2', function (e) { 
     alert('parent reacted to customClick.btn2'); 
    }); 

jQuery('a.btn1') 
    .click(function(){ 
     jQuery('div.child1').trigger('customClick.btn1'); 
    }); 

jQuery('a.btn2') 
    .click(function(){ 
     jQuery('div.child2').trigger('customClick.btn2'); 
    }); 

當我點擊a.btn1,正如所料,customClick.btn1事件被div.child1處理,而不是div.child2。不期望的是customClick事件會觸發div.parent上的處理程序customClick.btn1customClick.btn2。這是正確的嗎?有沒有辦法讓自定義事件與他們的命名空間泡泡?換句話說,當customClick.btn1被觸發時,並不是所有的customClick的父處理程序都被處理,只有那些處理customClick.btn1的處理程序。

+0

我認爲你需要從你的選擇器中去掉'#content',因爲在你的例子中沒有這個id的元素。這裏演示 - http://jsfiddle.net/HUALM/1/ – 2010-08-16 22:24:34

+0

對不起,#內容甚至不需要在那裏。我的壞 – 2010-08-16 23:15:11

+0

fyi我從選擇器字符串中刪除了#content – 2010-08-16 23:15:34

回答

3

看看文檔,它看起來像當你在做命名空間時,之前的部分.是事件類型。這就是被觸發的事件。

因此,.parent元素有2個customClick事件類型綁定到它。這就是爲什麼他們都開火。

從文檔:(。)http://api.jquery.com/bind/

如果EVENTTYPE字符串包含一個週期字符,然後該事件被命名空間。句點字符將事件與其名稱空間分開。例如,在調用.bind('click.name',處理程序)中,字符串click是事件類型,字符串名稱是命名空間。命名空間允許我們解除或觸發某種類型的事件而不影響其他事件。

這似乎是一個合理的預期,當事件出現泡沫時會考慮命名空間,但顯然不是。

您可以改爲檢查e.target.className以查看觸發了哪個元素。還必須有一種方法來獲取可以從事件對象中測試的命名空間。


編輯:

看起來你可以測試事件對象的像這樣的命名空間:

if(e.handleObj.namespace === 'btn1') 

編輯:

正如@ Nick Craver dem在下面的評論中提到,命名空間考慮冒泡時命名空間事件是而不是綁定到子級。就像這樣(這樣或那樣),它看起來像一個錯誤。

無論採用哪種方式,您仍應該能夠測試上面提到的名稱空間,因爲在兩種情況下,該屬性似乎都存在於Event對象中。

+0

這使得它稍微複雜一點:http://jsfiddle.net/nick_craver/bNbpN/如果'.child1'和'.child2' *未被綁定,它確實冒泡了,有一個命名空間,它是第一個綁定的處理程序,它不會傳遞它,本地冒泡的地方,我不確定這裏的* intended *行爲,但看起來像一個bug。 – 2010-08-16 22:35:22

+0

@尼克 - 那個*很奇怪。在我看來,預期的行爲是在冒泡時考慮命名空間。畢竟,如果有人花時間給'.parent'和後代命名空間,那麼在事件處理過程中需要匹配的命名空間是合理的期望,即使在冒泡的時候也是如此。我同意這看起來像一個錯誤。 – user113716 2010-08-16 22:44:07

+0

測試命名空間實際上並不能幫助您。如果您點擊a.btn1,div.parent將使用各自的命名空間處理'customClick.btn1'和'customClick.btn2'。使用firebug,你可以看到兩個處理程序都輸入了它們應該處理的名稱空間,並且它們的目標屬性都是div.child1。所以大問題是爲什麼在這種情況下div.child1觸發'customClick.btn2'。另外,我將發佈一個暫時的解決方案,而不是我正在嘗試做的事情。希望在美好的一天,我會回到命名空間事件語法。 – 2010-08-17 15:56:29

1

的Html

<div class="parent"> 
    <div class="child1" > 
    </div> 
    <div class="child2"> 
    </div> 
</div> 

<a class="btn1">customClick.btn1</a> 
<a class="btn2">customClick.btn2</a> 

jQuery的

jQuery('div.child1') 
    .bind('customClick', function (e) { 
     if(e.namespace == 'btn1'){ 
      console.log('child1 reacted to customClick.btn1'); 
     } 
    }); 


jQuery('div.child2') 
    .bind('customClick', function (e) { 
     if(e.namespace == 'btn2'){ 
      console.log('child2 reacted to customClick.btn2'); 
     } 
    }); 

jQuery('div.parent') 
    .bind('customClick', function (e) { 
     if(e.namespace == 'btn1'){ 
      console.log('parent reacted to customClick.btn1'); 
     } 
     if(e.namespace == 'btn2'){ 
      console.log('parent reacted to customClick.btn2'); 
     } 
    }) 


jQuery('a.btn1') 
    .click(function(){ 
     jQuery('div.child1').trigger({type:'customClick',namespace:'btn1'}); 
    }); 

jQuery('a.btn2') 
    .click(function(){ 
     jQuery('div.child2').trigger({type:'customClick',namespace:'btn2'}); 
    }); 

雖然這個作品,我喜歡做我以前做的方式。我用jQuery打開了一張票。 Ticket#6913感謝Nick Craver和patrick dw幫助確認問題。

+0

我剛要問你是否要提交錯誤報告。肯定需要修復。 – user113716 2010-08-17 16:27:51