Comment faire face aux différences de navigateur avec une case à cocher indéterminée

Primer: une case à cocher HTML peut être définie comme indeterminate, qui l'affiche comme ni cochée ni décochée. Même dans cet état indéterminé, il existe toujours un État booléen sous-jacent checked.

Cases à cocher Mac OS X dans différents états


Lorsqu'une case à cocher indéterminée est cochée, elle perd son état indeterminate. Selon le navigateur (Firefox), il peut en outre basculer la propriété checked.

Ce jsfiddle illustre la situation. Dans Firefox, en cliquant sur l'un des les cases à cocher les amènent une fois à basculer leur état checked sous-jacent initial. Dans IE, la propriété checked est laissée seule pour le premier clic.

Je voudrais que tous les navigateurs se comportent de la même manière, même si cela signifie javascript supplémentaire. Malheureusement, la propriété indeterminate est définie sur false avant que le gestionnaire onclick (ou onchange et jquery change) ne soit appelé, donc je ne peux pas détecter s'il est appelé pour un clic sur une case à cocher indeterminate ou non.

Le mouseup et keyup (pour la barre d'espace les événements toggle) montrent l'état indeterminate précédent, mais je préfère ne pas être si spécifique: il semble fragile.

Je pourrais maintenir une propriété distincte sur la case à cocher (data-indeterminate ou similaire), mais je voulais savoir s'il y a une solution simple qui me manque, et/ou si d'autres personnes ont des problèmes similaires.

21
demandé sur aaaidan 2012-04-11 06:45:41

4 réponses

Si vous souhaitez avoir une case à cocher inderterminate qui est cochée sur tous les navigateurs sur click (ou au moins sur IE, Chrome et FF5+), vous devez initialiser correctement l'attribut checked, comme indiqué ici http://jsfiddle.net/K6nrT/6/. j'ai écrit les fonctions suivantes pour vous aider:

/// 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;
}

Et la fonction intéressante qui repose sur la détection des fonctionnalités:

/// 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;
    }
}

Pas de trucs d'image, pas de jQuery, pas d'attributs supplémentaires et pas de gestion des événements impliqués. Cela ne repose que sur une simple initialisation JavaScript (notez que l'attribut "indéterminé" ne peut pas être défini dans le balisage HTML, donc l'initialisation JavaScript aurait été nécessaire de toute façon).

17
répondu Gyum Fox 2015-01-28 11:06:38

Cela a résolu mon problème

$(".checkbox").click(function(){
    $(this).change();
});
0
répondu Bitan Biswas 2015-04-23 11:41:41

Je ne suis pas sûr que l'utilisation de la fonction pour définir la valeur pour les cases à cocher indéterminées sera de bonnes solutions car:

  • vous devrez changer chaque endroit où vous les utilisez,
  • Si l'utilisateur soumet le formulaire sans cliquer sur les cases à cocher, votre backend recevra sera différent en fonction du navigateur.

Mais j'aime la façon intelligente de déterminer comment fonctionne le navigateur. Donc, vous pouvez vérifier {[1] } à la place habituelle window.navigator.userAgent.indexOf('Trident') >= 0 pour voir est-ce IE (ou peut-être autre navigateur qui fonctionne de manière inhabituelle).

Donc ma solution sera:

/// 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');
            }
        });
    });
}
0
répondu Артур Курицын 2016-11-07 20:03:29

Eh bien, faites votre propre image cliquable et utilisez du java (script) pour le faire se comporter comme ça. Je doute combien d'utilisateurs comprendraient cet état, alors faites attention où vous l'utilisez.

-1
répondu user613326 2013-04-03 19:15:09