对于复选框,将调用两次jQuery单击事件处理程序

时间:2020-12-18 00:02:13

I have a problem with the following code in an ASPX page:

我在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" />

In the browser (FF3.5 / IE8) I have the following problem:

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

  • if I click the checkbox (the small square), it works as expected
  • 如果我单击复选框(小方块),它按预期工作
  • if I click the checkbox's text ("Checkbox XYZ"), then the click event is fired twice, and the alert is shown twice.
  • 如果我单击复选框的文本(“Checkbox XYZ”),则单击事件将被触发两次,警报将显示两次。

I guess this has to do with the way the checkbox is rendered to HTML, which is like this:

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

How do I correctly setup the click event handler to prevent it from being called twice?

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

10 个解决方案

#1


56  

I have just experienced the same thing, but am not sure that event bubbling is causing my issue. I have a custom tree control, and when an item is opened, I use $(id).click() to attach a handler to all elements of a certain kind.

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

I suspect that this means that existing items elsewhere that already have the event, may then have it added again. I found that unbinding everything then re-binding solved my problem, thus:

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

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

#2


20  

I think it's because a <label> with a for attribute raises the click event of <input type="radio"> or <input type="checkbox"> element that is associated for when clicked.

我认为这是因为带有for属性的

So in your jQuery code, you set up a click event handler for both the <label> and the <input> inside <span class="test">. When clicking on the <label>, the click event handler that you set up on the label will execute, then the click event handler set up on the <input> will execute when the label raises the click event on the <input>.

因此,在您的jQuery代码中,您为中的

#3


14  

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

I was able to get my code working by stopping the event Propagation. It did not affect the status change of the checkbox.

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

#4


8  

Well after reading my question again, I found a way how to solve it.

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

Just add "input" to the jQuery selector:

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

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

#5


3  

Just use .mouseup rather than .click

只需使用.mouseup而不是.click

#6


2  

What you are seeing is event bubbling. The click event is first handled by the label and is then passed on to the checkbox. You get one alert for each. To prevent event bubbling you need to return false in your click handler.

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

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

However while this prevents event bubbling it also has the undesirable side effect of preventing the checkbox from changing state. So you'll need to code around that.

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

#7


2  

Solved: this to work with Firefox 3.6.12 and IE8.

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

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

The trick is to unbind("click"). before bind it to .click(fn); this will disabled the same event to fire twice.

诀窍是取消绑定(“点击”)。在将它绑定到.click(fn)之前;这将禁用同一事件两次。

Note that event "change" will not tricker at first time checkbox has been checked. So I use "click" instead.

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

#8


1  

I ran into the same issue with a click event, and found this article. In essence, if you have more than one jQuery document-ready functions inside the <body></body> tags, you can get multiple events. The fix is, of course, to not do that, or to unbind the click event and rebind it, as noted above. Sometimes, with multiple javascript libraries, it can be hard to avoid multiple document.ready()'s, so the unbind is a good workaround.

我遇到了与点击事件相同的问题,并发现了这篇文章。实质上,如果在 标记内有多个jQuery文档就绪函数,则可以获得多个事件。当然,修复程序是不执行此操作,或取消绑定click事件并重新绑定它,如上所述。有时,使用多个javascript库,很难避免多个document.ready(),因此unbind是一个很好的解决方法。

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

#9


1  

I know the question is far closed now, but I just have faced the same problem and I want to add the solution I found, may come in handy for similar problems on the future.

我知道这个问题现在已经关闭,但我只是遇到了同样的问题,我想添加我发现的解决方案,可能会对未来的类似问题派上用场。

When you add ASP code like:

当您添加ASP代码时:

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

the problem is that <asp:CheckBox ...> is not an html control, it's just something ASP made up from the twisted mind of some psycho invented, so the browser will receive something else.

问题是 不是一个html控件,它只是由一些心理发明的扭曲思维构成的ASP,所以浏览器会收到别的东西。 :checkbox>

The browser will receive something like:

浏览器将收到以下内容:

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

One of many possible solutions:

许多可能的解决方案之一:

The browser receive a span which content an input "checkbox" and a label for it with your text. Therefore my solution for this would be something like:

浏览器会收到一个内容,其中包含输入“复选框”以及带有文本的标签。因此,我的解决方案是这样的:

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

What happened up there? This selector $('.test > :checkbox') means: find the elements with the class "test" and bring any checkbox that it contains.

那里发生了什么?这个选择器$('。test>:checkbox')表示:找到带有“test”类的元素并带来它包含的任何复选框。

#10


0  

The function runs twice. Once from the inside and then it gets called again from inside itself. Simple add a return statement at the end.

该函数运行两次。一旦从内部开始,然后从内部再次调用它。简单地在最后添加一个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" />

This worked perfectly for me.

这对我来说非常合适。

#1


56  

I have just experienced the same thing, but am not sure that event bubbling is causing my issue. I have a custom tree control, and when an item is opened, I use $(id).click() to attach a handler to all elements of a certain kind.

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

I suspect that this means that existing items elsewhere that already have the event, may then have it added again. I found that unbinding everything then re-binding solved my problem, thus:

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

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

#2


20  

I think it's because a <label> with a for attribute raises the click event of <input type="radio"> or <input type="checkbox"> element that is associated for when clicked.

我认为这是因为带有for属性的

So in your jQuery code, you set up a click event handler for both the <label> and the <input> inside <span class="test">. When clicking on the <label>, the click event handler that you set up on the label will execute, then the click event handler set up on the <input> will execute when the label raises the click event on the <input>.

因此,在您的jQuery代码中,您为中的

#3


14  

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

I was able to get my code working by stopping the event Propagation. It did not affect the status change of the checkbox.

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

#4


8  

Well after reading my question again, I found a way how to solve it.

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

Just add "input" to the jQuery selector:

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

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

#5


3  

Just use .mouseup rather than .click

只需使用.mouseup而不是.click

#6


2  

What you are seeing is event bubbling. The click event is first handled by the label and is then passed on to the checkbox. You get one alert for each. To prevent event bubbling you need to return false in your click handler.

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

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

However while this prevents event bubbling it also has the undesirable side effect of preventing the checkbox from changing state. So you'll need to code around that.

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

#7


2  

Solved: this to work with Firefox 3.6.12 and IE8.

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

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

The trick is to unbind("click"). before bind it to .click(fn); this will disabled the same event to fire twice.

诀窍是取消绑定(“点击”)。在将它绑定到.click(fn)之前;这将禁用同一事件两次。

Note that event "change" will not tricker at first time checkbox has been checked. So I use "click" instead.

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

#8


1  

I ran into the same issue with a click event, and found this article. In essence, if you have more than one jQuery document-ready functions inside the <body></body> tags, you can get multiple events. The fix is, of course, to not do that, or to unbind the click event and rebind it, as noted above. Sometimes, with multiple javascript libraries, it can be hard to avoid multiple document.ready()'s, so the unbind is a good workaround.

我遇到了与点击事件相同的问题,并发现了这篇文章。实质上,如果在 标记内有多个jQuery文档就绪函数,则可以获得多个事件。当然,修复程序是不执行此操作,或取消绑定click事件并重新绑定它,如上所述。有时,使用多个javascript库,很难避免多个document.ready(),因此unbind是一个很好的解决方法。

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

#9


1  

I know the question is far closed now, but I just have faced the same problem and I want to add the solution I found, may come in handy for similar problems on the future.

我知道这个问题现在已经关闭,但我只是遇到了同样的问题,我想添加我发现的解决方案,可能会对未来的类似问题派上用场。

When you add ASP code like:

当您添加ASP代码时:

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

the problem is that <asp:CheckBox ...> is not an html control, it's just something ASP made up from the twisted mind of some psycho invented, so the browser will receive something else.

问题是 不是一个html控件,它只是由一些心理发明的扭曲思维构成的ASP,所以浏览器会收到别的东西。 :checkbox>

The browser will receive something like:

浏览器将收到以下内容:

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

One of many possible solutions:

许多可能的解决方案之一:

The browser receive a span which content an input "checkbox" and a label for it with your text. Therefore my solution for this would be something like:

浏览器会收到一个内容,其中包含输入“复选框”以及带有文本的标签。因此,我的解决方案是这样的:

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

What happened up there? This selector $('.test > :checkbox') means: find the elements with the class "test" and bring any checkbox that it contains.

那里发生了什么?这个选择器$('。test>:checkbox')表示:找到带有“test”类的元素并带来它包含的任何复选框。

#10


0  

The function runs twice. Once from the inside and then it gets called again from inside itself. Simple add a return statement at the end.

该函数运行两次。一旦从内部开始,然后从内部再次调用它。简单地在最后添加一个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" />

This worked perfectly for me.

这对我来说非常合适。