我有一个三态复选框,我需要在用户点击它时触发更改事件,但当复选框的状态为“INDETERMINATE”时,IE将不会触发它(浏览器错误可能?)。登记/> 作为IE的解决方法,我可以通过编程方式触发更改事件,但这对我的情况不起作用,因为我需要知道事件是否因为用户实际点击它而被触发。
Fiddle here / Test on IE and Chrome
<label for="cb">
<input id="cb" type="checkbox" />
click me
</label>
var checkbox = document.getElementById("cb");
checkbox.indeterminate = true;
$('#cb').change(function(){alert('Change Event')});
我已阅读这篇文章https://github.com/jquery/jquery/issues/1698和How to deal with browser differences with indeterminate checkbox,但我可以为我的案例找到具体的解决方案。
任何想法如何解决这个问题?
提前谢谢。
答案 0 :(得分:6)
复选框输入只能有两种状态:已选中或未选中。不确定状态仅是可视状态,它掩盖了复选框的实际状态。
首次点击其不确定设置为true
的复选框时,只需将其更改为false
,复选框即会显示其真实状态。因此,从“不确定”到“已检查”或“未选中”的更改不是实际状态的更改,也不会触发onchange
事件。
有趣的是,唯一正确实现此行为的浏览器是IE。您可以在IE和其他浏览器中测试它:
document.getElementById("cb1").indeterminate = true;
document.getElementById("cb2").indeterminate = true;
<label for="cb1"><input id="cb1" type="checkbox" checked="checked" />I'm actually checked</label>
<label for="cb2"><input id="cb2" type="checkbox" />I'm actually unchecked</label>
在IE中,第一次点击将显示复选框的实际状态。在Chrome中,它会将真实状态更改为其他实际状态。
虽然IE技术上的实现是正确的,但其他浏览器的实现更为实用。对于大多数应用程序,视觉“不确定”状态需要被视为真实状态,就像“已检查”和“未检查”一样,这意味着从这3个状态中的任何状态到另一个状态的更改都应触发onchange
事件
如何解决这个问题?嗯,最明显的答案可能是仅为IE注册一次点击事件,就像https://github.com/jquery/jquery/issues/1698建议的那样。
// As other browsers already fire the change event,
// only bind the listener for IE.
if ( window.navigator.userAgent.indexOf('Trident') >= 0 ) {
$(function(){
// Pointer events in IE10, IE11 can be handled as mousedown.
$(document).on('mousedown', 'input', function(){
// Only fire the change event if the input is indeterminate.
if ( this.indeterminate ) {
$(this).trigger('change');
}
});
});
}
但是,A. Wolff给出的更通用的方法可能是更好的方法,因为尽可能避免使用特定于浏览器的代码总是更好:
var checkbox = document.getElementById("cb");
checkbox.indeterminate = true;
$('#cb').one('click', function () {
if (!this.checked) {
this.checked = true;
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
this.dispatchEvent(evt);
}
}).change(function (e) {
console.log(e);
alert(e.originalEvent)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="cb">
<input id="cb" type="checkbox" />click me
</label>