jQuery:用于检测复选框是否被检查的问题

问题描述:

我为我的CMS创建了一个小型jQuery插件,用于设置某些表单输入类型(只是收音机,此时为复选框)。它通过隐藏原始表单元素并在输入的位置放置一个普通的HTML元素(用于CSS样式化)来工作。然后它检测元素上的操作并相应地更新原始输入。此外,它还将在关联标签被点击时起作用。这里是我的代码:jQuery:用于检测复选框是否被检查的问题

jQuery.fn.ioForm = function() { 
    return this.each(function(){ 
     //For each input element within the selector. 
     $('input', this).each(function() { 
      var type = $(this).attr('type'); 

      //BOF: Radios and checkboxes. 
      if (type == 'radio' || type == 'checkbox') { 
       var id = $(this).attr('id'); 
       checked = ''; 

       if ($(this).attr('checked')) { 
        checked = 'checked'; 
       } 

       //Add the pretty element and hide the original. 
       $(this).before('<span id="pretty_'+ id +'" class="'+ type +' '+ checked +'"></span>'); 
       $(this).css({ display: 'none' }); 

       //Click event for the pretty input and associated label. 
       $('#pretty_'+ id +', label[for='+ id +']').click(function() { 
        if (type == 'radio') { 
         //Radio must uncheck all related radio inputs. 
         $(this).siblings('span.radio.checked').removeClass('checked'); 
         $(this).siblings('input:radio:checked').removeAttr('checked'); 

         //And then check itself. 
         $('#pretty_'+ id).addClass('checked'); 
         $('#'+ id).attr('checked', 'checked'); 
        } else if (type == 'checkbox') { 
         if ($('#'+ id).attr('checked')) { 
          //Checkbox must uncheck itself if it is checked. 
          $('#pretty_'+ id).removeClass('checked'); 
          $('#'+ id).removeAttr('checked'); 
         } else { 
          //Checkbox must check itself if it is unchecked. 
          $('#pretty_'+ id).addClass('checked'); 
          $('#'+ id).attr('checked', 'checked'); 
         } 


        } 
       }); 
      } //EOF: Radios and checkboxes. 


     }); 
    }); 
}; 

这对于无线的伟大工程,但该复选框,似乎点击复选框标签第二次时被卡住 - 标签的第一次点击它成功地改变到合适的状态,但再次点击标签不会改变它(但复选框本身仍然正常工作)。它在IE8中完美运行。

我检查了ID是正确的,它是。我也尝试了其他一些方法,我偶然检查了复选框是否被选中,但他们要么给出了相同的结果,要么完全失败。 :(

任何帮助将不胜感激。 谢谢:)

更新 下面是HTML,它是由一个PHP类生成。这是jQuery的已运行和在跨度元素的加入后:

<div> 
    <p class="label">Test:</p> 
    <span id="pretty_test_published_field" class="checkbox"></span> 
    <input class="checkbox" id="test_published_field" name="test" type="checkbox" value="published"> 
    <label for="test_published_field" class="radio">Published</label> 
    <span id="pretty_test_draft_field" class="checkbox"></span> 
    <input checked="checked" class="checkbox" id="test_draft_field" name="test" type="checkbox" value="draft"> 
    <label for="test_draft_field" class="radio">Draft</label> 
</div> 

只需使用无误,并极其简单DOM checked财产。 jQuery对此并不合适,显然使得最简单的JavaScript任务之一容易出错并且令人困惑。这也适用于idtype属性。

$('input', this).each(function() { 
    var type = this.type; 
    if (type == 'radio' || type == 'checkbox') { 
     var id = this.id; 
     var checked = this.checked ? 'checked' : ''; 

     // Etc. 
    } 
}); 

UPDATE

点击一个复选框相关的<label>元素的默认操作是切换复选框的checkedness。我还没有用隐藏的表单元素的标签自己尝试过,但是由于您不阻止浏览器的默认点击操作,因此可能仍然会发生切换。请尝试以下操作:

//Click event for the pretty input and associated label. 
$('#pretty_'+ id +', label[for='+ id +']').click(function(evt) { 
    if (type == 'radio') { 
     //Radio must uncheck all related radio inputs. 
     $(this).siblings('span.radio.checked').removeClass('checked'); 
     $(this).siblings('input:radio:checked').each(function() { 
      this.checked = false; 
     }); 

     //And then check itself. 
     $('#pretty_'+ id).addClass('checked'); 
     $('#'+ id)[0].checked = true; 

     evt.preventDefault(); 
    } else if (type == 'checkbox') { 
     if ($('#'+ id).attr('checked')) { 
      //Checkbox must uncheck itself if it is checked. 
      $('#pretty_'+ id).removeClass('checked'); 
      $('#'+ id)[0].checked = false; 
     } else { 
      //Checkbox must check itself if it is unchecked. 
      $('#pretty_'+ id).addClass('checked'); 
      $('#'+ id)[0].checked = true; 
     } 

     evt.preventDefault(); 
    } 
}); 
+1

+1用于思考外部jQuery :) – alex 2010-06-23 13:16:49

+0

刚试过这个,它没有任何区别。问题似乎是它没有更新检查的状态,或者没有检测到它。我也按照吉姆的建议使用了现场,但这也没有什么区别。如果它有所作为,那么checked属性不会在Chrome开发人员工具的元素显示中出现或消失。如果我在我的“漂亮”旁边显示原始复选框,它仍会像“漂亮”一样检查/取消选中。此外,这个问题似乎只是从我把它变成一个jQuery函数开始。 – Fourjays 2010-06-23 13:47:19

+0

修改我的回答。 – 2010-06-23 14:21:23

我已经对奇accassion发现,我需要使用的替代:

$("#checkboxID").is(':checked'); 

这可能是或不是在你的情况下的替代方案,但值得注意。此外,如果发生对dom的更改,则可能必须添加“实时”事件,而不是“点击”。即

.click(function() 

.live('click', function() 

吉姆

+0

不幸的是没有任何区别。 :( – Fourjays 2010-06-23 13:49:12

+0

通常用于与我一起工作的checboxes。:D – workdreamer 2011-09-12 19:22:43

您能向我们展示HTML吗?我正在查看是否为HTML中的复选框设置了value属性。有可能破坏它。

<input type="checkbox" value="This May Break Checkbox" /> 
<input type="checkbox" name="This Checkbox Works" /> 
+0

添加了HTML到我原来的问题。它确实有一个值来自PHP类。我现在已经改变了这个类,所以它不再为复选框添加一个值。虽然没有改变。 :( 但是,当单击标签时,复选框本身(用于测试的显示旁边)现在不会改变,但“漂亮”的人在卡住前会更新一次(因为复选框没有被实际选中/取消选中) 所以看来问题是通过标签实际检查复选框。 – Fourjays 2010-06-23 14:24:33

复选框的checked属性被映射到defaultChecked属性和checked属性。改为使用prop()方法。

如果elem是复选框,使用:

elem.checked 

$(elem).prop("checked") 

这给我们的复选框,并变化的状态变化的正确状态信息。

这似乎是在许多情况下混淆的原因。因此,请记住背后的根本原因。