jQuery / Javascript:单击复选框上的事件和“已检查”属性

时间:2022-11-28 20:52:42

The code:

$('input.media-checkbox').live('click', function(e){

    e.preventDefault();
    var that = $(this);

    if (that.attr('checked') == 'checked'){

        var m = that.attr('media');
        var mid = 'verify_' + m;
        that.parents('div.state-container').find('ul.' + mid).remove();
        that.attr('checked', false);
    } else {

        var url = AJAX_URL;

        $.ajax({
           type: 'GET',
           url: url,
           dataType: 'html',
           success: function(data){

                that.parents('li').siblings('li.verification').children('div.media-verification').append(data).fadeIn(500);
                that.attr('checked', 'checked');
           }
        }); 
    }

    return false;
});

I am ajaxing in a form, then firing the click event on relevant checkboxes to ajax in another partial if necessary. The form is inserted nicely, and the click events are fired, checking the boxes that need to be checked and firing the second ajax, since the checked attribute of the checkbox was initially false.

我在一个表单中ajaxing,然后在相关的复选框上触发click事件到另一个部分的ajax,如果有必要的话。很好地插入表单,并触发单击事件,检查需要检查的框并触发第二个ajax,因为复选框的checked属性最初为false。

What's curdling my cheese is if I UNCHECK one of those boxes. Despite e.preventDefault(), the checked attribute is set to false BEFORE the test, so the if statement always executes the else statement. I've also tried this with $.is(':checked'), so I'm completely baffled.

如果我取消其中一个盒子,我的奶酪是什么?尽管有e.preventDefault(),但在测试之前,checked属性设置为false,因此if语句始终执行else语句。我也用$ .is(':checked')试过这个,所以我完全不知所措。

It appears that unchecked -> checked state reads the original state, but checked -> unchecked doesn't. Any help?

看来unchecked - > checked状态读取原始状态,但是选中 - > unchecked则没有。有帮助吗?

6 个解决方案

#1


15  

B.E., I know it has been a year but I think I found the solution,

B.E.,我知道已经过了一年,但我想我找到了解决方案,

The issue here is that the click event actually get's called and runs BEFORE the "checked" property is added to the checkbox input. So the function runs, looks to see if the input has the "checked" attribute, and runs the else condition. THEN the element is given the "checked" property.

这里的问题是实际调用click事件并在“checked”属性添加到复选框输入之前运行。因此该函数运行,查看输入是否具有“checked”属性,并运行else条件。然后该元素被赋予“已检查”属性。

I just ran into this as well, and my solution was to bind the function to the change function rather than the click function, as change only fires AFTER the checked property has been updated on the input.

我也碰到了这个,我的解决方案是将函数绑定到更改函数而不是单击函数,因为更改仅在输入更新checked属性后触发。

Hopefully this help you, and if not, anyone else who happens to stumble upon this post while experiencing a similar issue.

希望这可以帮助你,如果没有,那么在遇到类似问题时碰巧偶然发现这篇文章的其他人。

#2


2  

Well, right. You have set the live event, so I think your script might also be responding to setting it as checked, but I can't totally tell what you're trying for here without seeing markup, but here's my rewrite.

好吧,对。你已经设置了直播事件,所以我认为你的脚本可能也会响应将其设置为已选中,但我不能完全告诉你在这里尝试的是什么而没有看到标记,但这是我的重写。

$('input.media-checkbox').live('click', function(e){

    if ($(this).is(':checked')) {
        var m = $(this).attr('media');
        var mid = 'verify_' + m;
        $(this).parents('div.state-container')
            .find('ul.' + mid)
            .remove();
        $(this).attr('checked', false);
    } else {
        var url = AJAX_URL;
        var that = this;
        $.ajax({
            type: 'GET',
            url: url,
            dataType: 'html',
            success: function(data) {
                $(that).parents('li')
                    .siblings('li.verification')
                    .children('div.media-verification')
                    .append(data)
                    .fadeIn(500);
                $(that).attr('checked', true);
            }
        }); 
    }
    return false;

});

#3


1  

Try using e.stopPropagation() instead of e.preventDefault() and also remove return false. Returning false in jQuery is equivalent to e.stopPropagation() + e.preventDefault(). e.preventDefault() prevents the checkbox from being checked.

尝试使用e.stopPropagation()而不是e.preventDefault(),并删除return false。在jQuery中返回false等同于e.stopPropagation()+ e.preventDefault()。 e.preventDefault()可以防止选中复选框。

#4


0  

It seems to be a due to asynchronous requests. The execution goes past $.ajax, before it's success callback fires. When you click the checkbox again, it's state has not yet been updated by the previous request's callback. What you can try is to disable the checkbox control prior to firing the ajax call, and enable it again within the success callback:

这似乎是由于异步请求。在成功回调激活之前,执行过了$ .ajax。当您再次单击该复选框时,前一个请求的回调尚未更新其状态。您可以尝试在触发ajax调用之前禁用复选框控件,并在成功回调中再次启用它:

that.attr("disabled", "disabled");
var url = AJAX_URL;   
$.ajax({
    type: 'GET',
    url: url,
    dataType: 'html',
    success: function(data){

        that.parents('li').siblings('li.verification').children('div.media-verification').append(data).fadeIn(500);
        that.attr('checked', 'checked');
        that.removeAttr('disabled');
    }
}); 

That will ensure that two successive clicks will not lead to unpredictable behaviour. The other way would be to use a synchronous request, i.e. async: false but that will block the entire browser for it's duration.

这将确保连续两次点击不会导致不可预测的行为。另一种方法是使用同步请求,即async:false,但这将阻止整个浏览器的持续时间。

#5


0  

I think it's due to a weird bug in IE. Check/set attribute defaultChecked along with checked. Try this in your if condition,

我认为这是由于IE中的一个奇怪的错误。检查/设置属性defaultChecked和checked。在if条件下尝试这个,

if (that.attr('checked')=='checked' || that.attr("defaultChecked")=='checked'){     
      var m = that.attr('media');  
      var mid = 'verify_' + m;
      that.parents('div.state-container').find('ul.' + mid).remove();
      that.attr('checked', false);
      that.attr('defaultChecked', false); 
} else {

#6


0  

This is probably only a partial answer, but in your test, $(this).attr('checked') should return true if checked and false if not. So just change your conditional to if (that.attr('checked'))

这可能只是部分答案,但在您的测试中,$(this).attr('checked')如果选中则返回true,否则返回false。所以只需将条件更改为if(that.attr('checked'))

#1


15  

B.E., I know it has been a year but I think I found the solution,

B.E.,我知道已经过了一年,但我想我找到了解决方案,

The issue here is that the click event actually get's called and runs BEFORE the "checked" property is added to the checkbox input. So the function runs, looks to see if the input has the "checked" attribute, and runs the else condition. THEN the element is given the "checked" property.

这里的问题是实际调用click事件并在“checked”属性添加到复选框输入之前运行。因此该函数运行,查看输入是否具有“checked”属性,并运行else条件。然后该元素被赋予“已检查”属性。

I just ran into this as well, and my solution was to bind the function to the change function rather than the click function, as change only fires AFTER the checked property has been updated on the input.

我也碰到了这个,我的解决方案是将函数绑定到更改函数而不是单击函数,因为更改仅在输入更新checked属性后触发。

Hopefully this help you, and if not, anyone else who happens to stumble upon this post while experiencing a similar issue.

希望这可以帮助你,如果没有,那么在遇到类似问题时碰巧偶然发现这篇文章的其他人。

#2


2  

Well, right. You have set the live event, so I think your script might also be responding to setting it as checked, but I can't totally tell what you're trying for here without seeing markup, but here's my rewrite.

好吧,对。你已经设置了直播事件,所以我认为你的脚本可能也会响应将其设置为已选中,但我不能完全告诉你在这里尝试的是什么而没有看到标记,但这是我的重写。

$('input.media-checkbox').live('click', function(e){

    if ($(this).is(':checked')) {
        var m = $(this).attr('media');
        var mid = 'verify_' + m;
        $(this).parents('div.state-container')
            .find('ul.' + mid)
            .remove();
        $(this).attr('checked', false);
    } else {
        var url = AJAX_URL;
        var that = this;
        $.ajax({
            type: 'GET',
            url: url,
            dataType: 'html',
            success: function(data) {
                $(that).parents('li')
                    .siblings('li.verification')
                    .children('div.media-verification')
                    .append(data)
                    .fadeIn(500);
                $(that).attr('checked', true);
            }
        }); 
    }
    return false;

});

#3


1  

Try using e.stopPropagation() instead of e.preventDefault() and also remove return false. Returning false in jQuery is equivalent to e.stopPropagation() + e.preventDefault(). e.preventDefault() prevents the checkbox from being checked.

尝试使用e.stopPropagation()而不是e.preventDefault(),并删除return false。在jQuery中返回false等同于e.stopPropagation()+ e.preventDefault()。 e.preventDefault()可以防止选中复选框。

#4


0  

It seems to be a due to asynchronous requests. The execution goes past $.ajax, before it's success callback fires. When you click the checkbox again, it's state has not yet been updated by the previous request's callback. What you can try is to disable the checkbox control prior to firing the ajax call, and enable it again within the success callback:

这似乎是由于异步请求。在成功回调激活之前,执行过了$ .ajax。当您再次单击该复选框时,前一个请求的回调尚未更新其状态。您可以尝试在触发ajax调用之前禁用复选框控件,并在成功回调中再次启用它:

that.attr("disabled", "disabled");
var url = AJAX_URL;   
$.ajax({
    type: 'GET',
    url: url,
    dataType: 'html',
    success: function(data){

        that.parents('li').siblings('li.verification').children('div.media-verification').append(data).fadeIn(500);
        that.attr('checked', 'checked');
        that.removeAttr('disabled');
    }
}); 

That will ensure that two successive clicks will not lead to unpredictable behaviour. The other way would be to use a synchronous request, i.e. async: false but that will block the entire browser for it's duration.

这将确保连续两次点击不会导致不可预测的行为。另一种方法是使用同步请求,即async:false,但这将阻止整个浏览器的持续时间。

#5


0  

I think it's due to a weird bug in IE. Check/set attribute defaultChecked along with checked. Try this in your if condition,

我认为这是由于IE中的一个奇怪的错误。检查/设置属性defaultChecked和checked。在if条件下尝试这个,

if (that.attr('checked')=='checked' || that.attr("defaultChecked")=='checked'){     
      var m = that.attr('media');  
      var mid = 'verify_' + m;
      that.parents('div.state-container').find('ul.' + mid).remove();
      that.attr('checked', false);
      that.attr('defaultChecked', false); 
} else {

#6


0  

This is probably only a partial answer, but in your test, $(this).attr('checked') should return true if checked and false if not. So just change your conditional to if (that.attr('checked'))

这可能只是部分答案,但在您的测试中,$(this).attr('checked')如果选中则返回true,否则返回false。所以只需将条件更改为if(that.attr('checked'))