Подтвердить что ты не робот

Как иметь дело с различиями браузера с неопределенным флажком

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 или подобное), но я хотел знать, есть ли простое решение, которое мне не хватает, и/или если у других людей возникают подобные проблемы.

4b9b3361

Ответ 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), чтобы заставить себя вести себя так. Я сомневаюсь, что многие пользователи поймут это состояние, поэтому будьте осторожны, где вы его используете.