当您单击它时,IE不会在不确定复选框上触发"更改"事件

Jer*_*ani 8 html checkbox jquery internet-explorer

我有一个三态复选框,我需要在用户点击它时触发更改事件,但当复选框的状态为"INDETERMINATE"时,IE将不会触发它(浏览器错误可能?).
因为解决IE的问题,我可以通过编程方式触发更改事件,但这对我的情况不起作用,因为我需要知道事件是否因为用户实际点击它而被触发.

在这里小提琴/在IE和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')});
Run Code Online (Sandbox Code Playgroud)

我已经阅读了这篇文章https://github.com/jquery/jquery/issues/1698以及如何使用不确定复选框处理浏览器差异,但我可以找到针对我的案例的特定解决方案.

任何想法如何解决这一问题?

先感谢您.

Rac*_*lan 10

复选框输入只能有两种状态:已选中或未选中.不确定状态仅是可视状态,它掩盖了复选框的实际状态.

第一次单击其不确定设置为的复选框时,true只需将其更改为false,复选框将显示其实际状态.因此,从"不确定"到"已检查"或"未检查"的更改不是实际状态的更改,也不会触发onchange事件.

有趣的是,唯一正确实现此行为的浏览器是IE.您可以在IE和其他浏览器中测试:

document.getElementById("cb1").indeterminate = true;
document.getElementById("cb2").indeterminate = true;
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

在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');
            }
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

但是,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)
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 这是解释它的一种方式,它似乎是 IE 团队的方式。我的解释是,无论不确定属性如何,单击复选框都会切换选中状态。在这种情况下,单击不确定复选框的正确行为是删除不确定标志,然后将检查更改为与其当前值相反。这是其他浏览器所做的。IE 仅将不确定状态设置为 false,但不会切换底层选中状态。这就是它不触发更改事件的原因。 (2认同)