2015-11-04 2 views
4

У меня есть флажок tri-state, и мне нужно, чтобы событие изменения было запущено, когда пользователь нажимает на него, но IE не запускает его, когда состояние флажка находится на «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

HTTPS://github.com/jquery/jquery/issues/1698 –

+0

Я уже прочитал это и не буду работать для своего дела –

+0

Я просто протестировал его, не работает –

ответ

5

Входы счетчика могут иметь только два состояния: отмечены или сняты флажки. Неопределенное состояние только визуально, и оно маскирует реальное состояние флажка.

В первый раз, когда вы нажмете флажок, который имеет неопределенный набор 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 правильная технически, реализация других браузеров является более практичной. Для большинства приложений визуальное «неопределенное» состояние должно рассматриваться как реальное состояние, как «проверено» и «непроверено», что означает, что переход от любого из этих трех состояний к другому должен инициировать событие 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>

+0

Чтобы уточнить правильное поведение, спецификации говорят https://html.spec.whatwg.org/multipage/forms.html#checkbox-state-(type=checkbox) , который говорит, что нажатие на неопределенный флажок должно переключать значение. Однако IE просто удаляет неопределенное состояние. –

+0

@ClarkPan Да, спецификации в этом документе сбивают с толку. Он четко указывает, что неопределенный атрибут * не имеет эффекта, кроме изменения внешнего вида элементов управления флажками. * Это означает, что поведение IE является правильным. Но затем он говорит: * Шаги активации предварительного щелчка состоят в том, чтобы установить проверочную проверку элемента на свое противоположное значение *, что противоречит первому утверждению, предполагая, что средство активации предварительного щелчка, щелкнув на флажке с неопределенным значением false. –

+0

это один из способов интерпретировать его, и это похоже на то, как работает команда IE. То, как я это интерпретирую, заключается в том, что, независимо от неопределенного атрибута, щелчок по флажку переключит проверенное состояние. В этом случае правильное поведение щелчка на неопределенном флажке будет состоять в том, чтобы удалить неопределенный флаг, а затем изменить флажок напротив его текущего значения. Это то, что делают другие браузеры. IE, только устанавливает неопределенное состояние как false, но не переключает базовое контролируемое состояние. Именно по этой причине он не запускает событие изменения. –

Смежные вопросы