我正在为我的CMS创建一个小型jQuery插件,用于设置某些表单输入类型(目前只有收音机,复选框)。它的工作原理是隐藏原始表单元素并在输入的位置放置一个普通的HTML元素(用于CSS样式)。然后,它检测元素上的操作并相应地更新原始输入。此外,单击关联标签时也可以使用它。这是我的代码:
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运行并添加到span元素之后:
<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>
答案 0 :(得分:5)
只使用绝对简单且极其简单的DOM checked
属性。 jQuery是不合适的,显然是最简单的JavaScript任务之一,容易出错并且容易混淆。这也适用于id
和type
属性。
$('input', this).each(function() {
var type = this.type;
if (type == 'radio' || type == 'checkbox') {
var id = this.id;
var checked = this.checked ? 'checked' : '';
// Etc.
}
});
<强>更新强>
单击与复选框关联的<label>
元素的默认操作是切换复选框的选中状态。我自己没有尝试使用隐藏表单元素的标签,但也许切换仍在发生,因为您没有阻止浏览器的默认点击操作。请尝试以下方法:
//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 :(得分:3)
我发现奇怪的怜悯,我需要使用替代方案:
$("#checkboxID").is(':checked');
这可能是您的情景中的替代方案,但值得注意。此外,您可能必须添加“实时”事件,而不是在发生对dom的更改时“点击”。即。
.click(function()
到
.live('click', function()
吉姆
答案 2 :(得分:1)
复选框的checked
属性映射到defaultChecked
属性,而不映射到checked
属性。请改用prop()
方法。
如果elem
是复选框,请使用:
elem.checked
或
$(elem).prop("checked")
这为我们提供了复选框的正确状态信息,并随着状态的变化而变化。
这似乎是许多情况下混淆的原因。因此,记住这背后的根本原因是很好的。
答案 3 :(得分:0)
你能告诉我们HTML吗?我想看看你是否为HTML中的复选框设置了一个value属性。有可能打破它。
<input type="checkbox" value="This May Break Checkbox" />
<input type="checkbox" name="This Checkbox Works" />