为复选框调用两次jQuery单击事件处理程序

时间:2009-10-08 09:27:51

标签: asp.net jquery checkbox

我在ASPX页面中遇到以下代码的问题:

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

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

在浏览器(FF3.5 / IE8)中,我遇到以下问题:

  • 如果我点击复选框(小方块),它会按预期工作
  • 如果我单击复选框的文本(“Checkbox XYZ”),则会触发click事件两次,并且警报会显示两次。

我想这与复选框呈现为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>

如何正确设置click事件处理程序以防止它被调用两次?

11 个答案:

答案 0 :(得分:57)

我刚刚经历过同样的事情,但我不确定事件冒泡是否会导致我的问题。我有一个自定义树控件,当一个项打开时,我使用$(id).click()将处理程序附加到某种类型的所有元素。

我怀疑这意味着已经拥有该事件的其他地方的现有项目可能会再次添加它。我发现取消绑定所有内容然后重新绑定解决了我的问题,因此:

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

答案 1 :(得分:20)

我认为这是因为带有<label>属性的for会引发点击时关联的<input type="radio"><input type="checkbox">元素的点击事件。

因此,在您的jQuery代码中,您为<label>内的<input><span class="test">设置了点击事件处理程序。单击<label>时,将执行您在标签上设置的单击事件处理程序,然后在<input>上设置的单击事件处理程序将在标签引发{上的click事件时执行{1}}。

答案 2 :(得分:14)

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

我能够通过停止事件传播来使我的代码工作。它不会影响复选框的状态更改。

答案 3 :(得分:8)

再次阅读我的问题之后,我找到了解决问题的方法。

只需将“input”添加到jQuery选择器:

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

答案 4 :(得分:3)

只需使用.mouseup而不是.click

答案 5 :(得分:2)

您所看到的是事件冒泡。 click事件首先由标签处理,然后传递给复选框。你会得到一个警报。要防止事件冒泡,您需要在单击处理程序中返回false。

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

然而,虽然这可以防止事件冒泡,但它也具有防止复选框改变状态的不良副作用。所以你需要围绕它进行编码。

答案 6 :(得分:2)

已解决:这适用于Firefox 3.6.12和IE8。

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

诀窍是unbind("click").将其绑定到.click(fn)之前;这将禁止同一事件发射两次。

请注意,事件“更改”不会在第一次复选框时检查复选框。所以我改用“点击”。

答案 7 :(得分:1)

我遇到了与点击事件相同的问题,并找到了this文章。从本质上讲,如果你有多个jQuery文档就绪函数     <body></body> 标签,你可以得到多个事件。当然,修复程序是不执行此操作,或取消绑定click事件并重新绑定它,如上所述。有时,使用多个javascript库,很难避免多个document.ready(),因此unbind是一个很好的解决方法。

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

答案 8 :(得分: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”类的元素,并带来它包含的任何复选框。

答案 9 :(得分: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" />

这对我来说非常合适。

答案 10 :(得分:0)

我在选择器上遇到了同样的问题。并最终使用 off() 函数。

$('body').off('click').on('click', '<your selector>', function(){
    // Your code                
});