Входы счетчика могут иметь только два состояния: отмечены или сняты флажки. Неопределенное состояние только визуально, и оно маскирует реальное состояние флажка.
В первый раз, когда вы нажмете флажок, который имеет неопределенный набор 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>
HTTPS://github.com/jquery/jquery/issues/1698 –
Я уже прочитал это и не буду работать для своего дела –
Я просто протестировал его, не работает –