Как иметь дело с различиями браузера с неопределенным флажком
Primer: Флажок HTML может быть установлен как indeterminate
, который отображает его как ни проверенный, ни снятый. Даже в этом неопределенном состоянии все еще существует базовое состояние boolean checked
.
![Mac OS X checkboxes in various states]()
При щелчке по неопределенному флажку он теряет состояние indeterminate
. В зависимости от браузера (Firefox) он может дополнительно переключить свойство checked
.
Этот jsfiddle иллюстрирует ситуацию. В Firefox одно нажатие на один из этих флажков заставляет их переключать исходное базовое состояние checked
. В IE свойство checked
оставлено в покое для первого щелчка.
Я бы хотел, чтобы все браузеры ведут себя одинаково, даже если это означает дополнительный javascript. К сожалению, для свойства indeterminate
установлено значение false до того, как вызывается обработчик onclick
(или onchange
и jquery change
), поэтому я не могу определить, вызывал ли он клик на флажке indeterminate
или нет.
События mouseup
и keyup
(для переключения пробела) показывают предыдущее состояние indeterminate
, но я бы предпочел не быть таким специфичным: он кажется хрупким.
Я мог бы сохранить отдельное свойство в флажке (data-indeterminate
или подобное), но я хотел знать, есть ли простое решение, которое мне не хватает, и/или если у других людей возникают подобные проблемы.
Ответы
Ответ 1
Если вы хотите установить флажок inderterminate, который будет проверяться во всех браузерах при нажатии (или, по крайней мере, на IE, Chrome и FF5 +), вам необходимо правильно инициализировать проверенный атрибут, как показано здесь http://jsfiddle.net/K6nrT/6/. Я написал следующие функции, которые помогут вам:
/// Gives a checkbox the inderminate state and the right
/// checked state so that it becomes checked on click
/// on click on IE, Chrome and Firefox 5+
function makeIndeterminate(checkbox)
{
checkbox.checked = getCheckedStateForIndeterminate();
checkbox.indeterminate = true;
}
и интересная функция, которая зависит от обнаружения функции:
/// Determine the checked state to give to a checkbox
/// with indeterminate state, so that it becomes checked
/// on click on IE, Chrome and Firefox 5+
function getCheckedStateForIndeterminate()
{
// Create a unchecked checkbox with indeterminate state
var test = document.createElement("input");
test.type = "checkbox";
test.checked = false;
test.indeterminate = true;
// Try to click the checkbox
var body = document.body;
body.appendChild(test); // Required to work on FF
test.click();
body.removeChild(test); // Required to work on FF
// Check if the checkbox is now checked and cache the result
if (test.checked)
{
getCheckedStateForIndeterminate = function () { return false; };
return false;
}
else
{
getCheckedStateForIndeterminate = function () { return true; };
return true;
}
}
Нет трюков изображения, нет jQuery, нет дополнительных атрибутов и нет обработки событий. Это зависит только от простой инициализации JavaScript (обратите внимание, что атрибут "undefined" не может быть установлен в разметке HTML, поэтому в любом случае потребуется инициализация JavaScript).
Ответ 2
Это решило мою проблему
$(".checkbox").click(function(){
$(this).change();
});
Ответ 3
Я не уверен, что использование функции для установки значения для неопределенных флажков будет хорошим решением, потому что:
- вам нужно будет изменить каждое место, где вы их используете,
- если пользователь отправит форму без нажатия на флажки, значение, которое
ваш бэкэнд будет получать, будет отличаться в зависимости от браузера.
Но мне нравится умный способ определить, как работает браузер.
Таким образом, вы можете проверить isCheckedAfterIndeterminate()
вместо обычного window.navigator.userAgent.indexOf('Trident') >= 0
, чтобы увидеть это IE (или, возможно, другой браузер, который работает необычным образом).
Итак, мое решение будет:
/// Determine the checked state to give to a checkbox
/// with indeterminate state, so that it becomes checked
/// on click on IE, Chrome and Firefox 5+
function isCheckedAfterIndeterminate()
{
// Create a unchecked checkbox with indeterminate state
var test = document.createElement("input");
test.type = "checkbox";
test.checked = false;
test.indeterminate = true;
// Try to click the checkbox
var body = document.body;
body.appendChild(test); // Required to work on FF
test.click();
body.removeChild(test); // Required to work on FF
// Check if the checkbox is now checked and cache the result
if (test.checked) {
isCheckedAfterIndeterminate = function () { return false; };
return false;
} else {
isCheckedAfterIndeterminate = function () { return true; };
return true;
}
}
// Fix indeterminate checkbox behavoiur for some browsers.
if ( isCheckedAfterIndeterminate() ) {
$(function(){
$(document).on('mousedown', 'input', function(){
// Only fire the change event if the input is indeterminate.
if ( this.indeterminate ) {
this.indeterminate = false;
$(this).trigger('change');
}
});
});
}
Ответ 4
Хорошо сделайте свое собственное clickable изображение и используйте некоторую java (script), чтобы заставить себя вести себя так.
Я сомневаюсь, что многие пользователи поймут это состояние, поэтому будьте осторожны, где вы его используете.