【问题标题】:jQuery/Javascript: Click event on a checkbox and the 'checked' attributejQuery / Javascript:复选框和“选中”属性上的单击事件
【发布时间】:2011-02-16 16:35:45
【问题描述】:

代码:

$('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;
});

我在表单中进行 ajax,然后在必要时触发相关复选框上的单击事件以在另一个部分中进行 ajax。表单被很好地插入,点击事件被触发,选中需要检查的框并触发第二个 ajax,因为复选框的 checked 属性最初是 false

如果我取消选中其中一个框,我的奶酪会变得凝固。尽管e.preventDefault()checked 属性在测试之前设置为false,所以if 语句总是执行else 语句。我也用$.is(':checked') 试过这个,所以我完全感到困惑。

似乎 unchecked -> checked 状态会读取原始状态,但 checked -> unchecked 不会。有什么帮助吗?

【问题讨论】:

  • 你试过return false;而不是e.preventDefault吗?另外,你用过function(e) { e = e || event; ... } 吗?
  • return false,是的 - 它在代码的末尾。它应该在if 闭包内吗?我不熟悉第二段代码......它是做什么用的?
  • 第二位检查e 是否为非空,如果不是,则分配给全局event 变量。
  • @Jacob Relkin - e = e || event 在 jQuery 中是不必要的,它会为您标准化事件对象。

标签: javascript jquery events click


【解决方案1】:

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

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

我也遇到了这个问题,我的解决方案是将函数绑定到 change 函数而不是 click 函数,因为 change 仅在输入的已检查属性更新后才会触发。

希望这对您有所帮助,如果没有,其他任何碰巧在遇到类似问题时偶然发现这篇文章的人。

【讨论】:

  • 针对原始项目进行了测试(仍在生产中,有解决方法) - 它可以工作。赞一个!
【解决方案2】:

嗯,没错。您已经设置了 live 事件,所以我认为您的脚本也可能会响应将其设置为已选中,但如果没有看到标记,我无法完全说出您在这里尝试的内容,但是这是我的重写。

$('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;

});

【讨论】:

  • 我需要.live 事件处理程序,因为有问题的表单在加载时不在文档中 - 之后它是 ajax 的。直接设置.bind 是行不通的。
【解决方案3】:

尝试使用e.stopPropagation() 代替e.preventDefault(),同时删除return false。在 jQuery 中返回 false 等价于 e.stopPropagation() + e.preventDefault()e.preventDefault() 阻止复选框为 checked

【讨论】:

    【解决方案4】:

    这似乎是由于异步请求。在成功回调触发之前,执行通过$.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');
        }
    }); 
    

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

    【讨论】:

    • 我喜欢这个 - 但不。被切换的复选框已经在 DOM 中 - 此 ajax 调用(用于第二个请求)是在测试 :checked 之后进行的,因此 ajax 请求的成功不会影响复选框的状态。选中一个复选框,jQuery 会读取复选框的正确起始状态 - 取消选中它,它会在触发 click 事件处理程序之前清除该框。这很奇怪。
    【解决方案5】:

    我认为这是由于 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】:

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

      【讨论】:

        猜你喜欢
        • 2014-07-20
        • 2011-10-25
        • 1970-01-01
        • 2013-02-23
        • 2013-09-27
        • 2012-08-12
        • 1970-01-01
        • 2016-11-14
        • 2015-08-06
        相关资源
        最近更新 更多