2009-10-08 52 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”的元素并带上它包含的任何复选框。