2009-10-08 96 views
19

我有下面的代碼在一個ASPX頁面中的問題調用兩次jQuery的單擊事件處理的一個複選框

  • 如果我點擊複選框(小廣場),它按預期工作
  • 如果我點擊複選框的文本(「複選框XYZ」),然後單擊事件被觸發兩次,顯示兩次警報。

我想這與該複選框被渲染到HTML的方式,這是這樣做的:

<span class="test"> 
<input id="ctl00_c1_cb1" type="checkbox" name="ctl00$c1$cb1" checked="checked"/> 
<label for="ctl00_c1_cb1">Checkbox XYZ</label> 
</span> 

如何正確設置單擊事件處理程序,以防止它被稱爲兩次?

回答

8

好了,在再次閱讀我的問題後,我找到了一種解決方法。

只需 「輸入」 添加到jQuery選擇:

<script type="text/javascript"> 
$(document).ready(function() { 
     $('.test input').click(function() { 
       alert("click") 
     }) 
}); 
</script> 
+5

@Martin - 我認爲這是因爲帶有'for' attrbute的標籤引發了附加元素的click事件。因此,在您的jQuery代碼中,您爲標籤和輸入設置了單擊事件處理程序。當點擊標籤時,您在標籤上設置的點擊事件處理程序將執行,然後在標籤引發單擊事件時,輸入上設置的點擊事件處理程序將執行。 – 2009-10-08 09:34:42

+0

UpVote!當使用帶有輸入的標籤時,我有同樣的事情,改爲div,並且它已經消失 – 2012-09-15 14:56:45

2

你們看到的是事件冒泡。點擊事件首先由標籤處理,然後傳遞給複選框。你會得到一個警報。爲了防止事件冒泡,你需要在你的點擊處理程序中返回false。

$(document).ready(function() { 
     $('.test').click(function() { 
       alert("Click"); 
       return false; 
     }) 
}); 

但是,雖然這可以防止事件冒泡,但它也有防止複選框更改狀態的不良副作用。所以你需要爲此編碼。

20

我認爲這是因爲具有for屬性的<label>屬性引發點擊時關聯的<input type="radio"><input type="checkbox">元素的點擊事件。

因此,在您的jQuery代碼中,您爲<label><input>內部的<span class="test">設置了單擊事件處理程序。點擊<label>時,標籤上設置的點擊事件處理程序將執行,然後<input>上設置的點擊事件處理程序將在標籤引發<input>上的點擊事件時執行。

+4

如果您更改'alert(「click」);'alert'(e.target。tagName);' - 首先看到'LABEL',然後'INPUT',表示標籤首先產生一個點擊事件,然後檢查/取消選中關聯的複選框,導致輸入引發一個點擊事件。 – 2010-08-07 13:03:39

+1

最後很好找到一個體面的問題解釋。 – 2012-06-13 09:08:08

14
$(document).ready(function() { 
    $('.test').click(function(event) { 
        event.stopImmediatePropagation(); 
        alert("Click"); 
        }) 
       } 
      ); 

我能通過停止事件傳播來讓我的代碼工作。它不會影響複選框的狀態更改。

+0

不幸的是,這並不適用於我(在IE8中測試)。當我點擊與複選框關聯的標籤/文本時,警告仍會顯示兩次。 – M4N 2009-12-04 18:23:48

56

我剛剛經歷過同樣的事情,但不確定事件冒泡是否導致我的問題。我有一個自定義的樹形控件,當打開一個項目時,我使用$(id).click()將處理程序附加到某種類型的所有元素。

我懷疑這意味着在其他地方已有的事件的現有項目可能會再次添加。我發現,一切都解除綁定,然後重新綁定解決我的問題,即:

$('img.load_expand').unbind("click").click(function() 
{ 
    // handler 
}); 
2

解決:這與Firefox 3.6.12和IE8工作。

$(function(){ 
     $("form input:checkbox").unbind("click") 
     .click(function(){ 
      val = $(this).val(); 
      alert(val); 
     }) 
    } 

訣竅是unbind("click").它結合.click(fn)之前;這將禁止相同的事件觸發兩次。

請注意,事件「更改」不會在第一次勾選複選框。所以我使用「點擊」來代替。

1

我遇到了同樣的問題,點擊事件,發現this文章。實質上,如果在標籤中有多個jQuery文檔就緒功能,則可以獲取多個事件。如上所述,修復當然不會這樣做,或解除綁定點擊事件並重新綁定它。有時,使用多個JavaScript庫時,可能很難避免多個document.ready(),所以解除綁定是一個很好的解決方法。

<code> 
$('#my-div-id').unbind("click").click(function() 
    { 
    alert('only click once!'); 
    } 
</code> 
3

只需使用.mouseup而不是。點擊

0

函數運行兩次。一旦從內部出現,然後從內部再次被調用。簡單地在最後添加一個return語句。

<script type="text/javascript"> 
$(document).ready(function() { 
    $('.test').click(function() { 
     alert("click"); 
     return false; 
    }) 
}); 
</script> 

<asp:CheckBox runat="server" Text="Checkbox XYZ" CssClass="test" ID="cb1" /> 

這對我來說非常合適。

1

我知道這個問題現在已經非常關閉了,但我只是遇到了同樣的問題,我想添加我找到的解決方案,可能會在未來出現類似的問題。

當您添加ASP代碼,如:

<asp:CheckBox runat="server" Text="Checkbox XYZ" CssClass="test" ID="cb1" /> 

問題是<asp:CheckBox ...>不是HTML控件,它只是一些ASP 從一些心理 的扭曲的心靈發明組成的,所以瀏覽器會收到別的東西。

瀏覽器將收到類似:

<span class="test"> 
    <input id="garbageforYourId_cb1" type="checkbox" name="garbage$moregarbage$cb1"/> 
    <label for="evenMoreGarbage_cb1">Checkbox XYZ</label> 
</span> 

是許多可能的解決方案:

瀏覽器中收到的跨度,其內容輸入「複選框」,併爲它與標籤你的文字。因此,我的解決方案是這樣的:

$('.test > :checkbox').click(function() { 
    if ($(this).attr("checked")) { 
     alert("checked!!!"); 
    } else { 
     alert("non checked!!!"); 
    } 
}); 

那裏發生了什麼?這個選擇器$('.test > :checkbox')表示:找到類「test」的元素並帶上它包含的任何複選框。