这是 Firefox 中的一个错误。请参阅错误 608180 - 双击/快速单击复选框标签无法按预期工作
由于历史原因(但在最近的版本中已修复),IE 有一个错误的事件模型,它会跳过第二个事件mousedown
和click
双击事件。请参阅错误 263 - 当心 IE 中的 DoubleClick。
我制作了一个插件,修复了 jQuery UI 按钮小部件中的一些错误,并在不久前解决了 Firefox 错误,应该不难适应您的非 jQuery UI 按钮。
提取了重要部分并将其改编为 s 内的嵌套复选框label
:
(function () {
var mdtarg, //last label mousedown target
mdchecked, //checked property when mousedown fired
fixedLabelSelector = '.fixedLabelCheckbox'; //edit as you see fit
$(document).on('mousedown', fixedLabelSelector, function (e) {
//only left clicks will toggle the label
if (e.which !== 1) return;
mdtarg = this;
mdchecked = this.control ? this.control.checked : $(this).find('input')[0].checked;
//reset mdtarg after mouseup finishes bubbling; prevents bugs with
//incorrect mousedown-mouseup sequences e.g.
//down IN label, up OUT, down OUT, up IN
$(document).one('mouseup', function () {
mdtarg = null;
});
}).on('mouseup', fixedLabelSelector, function (e) {
if (e.which !== 1) return;
if (mdtarg === this) {
var ch = this.control || $(this).find('input')[0];
//the click event is supposed to fire after the mouseup so
//we wait until mouseup and click finish bubbling and check if it
//had the desired effect
setTimeout(function () {
if (mdchecked === ch.checked) {
//else patch it manually
ch.checked = !ch.checked;
$(ch).change();
}
}, 0);
}
});
}());
Fiddle在 Firefox 中测试。
您必须将该fixedLabelCheckbox
类添加到包含您希望使用上面的代码修复的复选框的所有标签中。
无论您将脚本放在哪里,它都会起作用,并且只要标签具有相应的委托类/选择器,它还可以修复动态添加的复选框。
请注意,如果您使用其他库,这可能不会触发绑定在 jQuery 之外的更改处理程序。
如果你不想在你的标记中添加额外的类,你可以使用这个版本(更多的代码和更少的性能):
(function ($) {
function getControl(lbl) { //fallback for non-HTML5 browsers if necessary
return lbl.control || (lbl.htmlFor ? $('input[id="'+lbl.htmlFor+'"]')[0] : $(lbl).find('input')[0]);
}
var mdtarg, //last label mousedown target
mdchecked; //checked property when mousedown fired
$(document).on('mousedown', 'label', function (e) {
//only left clicks will toggle the label
if (e.which !== 1) return;
var ch = getControl(this);
if (!ch || ch.type !== 'checkbox') return;
mdtarg = this;
mdchecked = ch.checked;
//reset mdtarg after mouseup finishes bubbling; prevents bugs with
//incorrect mousedown-mouseup sequences e.g.
//down IN label, up OUT, down OUT, up IN
$(document).one('mouseup', function () {
mdtarg = null;
});
}).on('mouseup', 'label', function (e) {
if (e.which !== 1) return;
if (mdtarg === this) {
var ch = getControl(this);
//the click event is supposed to fire after the mouseup so
//we wait until mouseup and click finish bubbling and check if it
//had the desired effect
setTimeout(function () {
if (mdchecked === ch.checked) {
//else patch it manually
ch.checked = !ch.checked;
$(ch).change();
}
}, 0);
}
});
}(jQuery));
小提琴
正如您从上面的代码中看到的那样,此版本应该与标签的for
属性以及标签内的嵌套输入一起使用,而无需添加任何额外的标记。
关于禁用选择:您可以将user-select
问题中的注释放入 CSS 中,或者,如果浏览器不支持,user-select
也可以将此答案应用于您希望禁用选择的所有标签。