3
votes

Comment ignorer une option radio cachée avec la navigation au clavier dans Firefox et IE?

UPDATE Le problème suivant se produit même après avoir essayé les suggestions ici . Le dernier extrait de code montre les 3 approches pour masquer un bouton radio et interrompre la navigation au clavier / (touches fléchées haut / bas) dans le groupe radio de Firefox et IE.


Supposons que j'ai un groupe radio, chaque bouton radio avec son étiquette dans un DIV. J'utilise les touches fléchées (haut / bas) pour parcourir mes boutons radio une fois qu'au moins l'un d'entre eux a le focus.

Un des boutons radio de mon groupe radio est masqué. C'est dans une DIV qui a display: none; (mais j'ai aussi essayé visibilité: hidden et position: fixed; opacity: 0 comme alternatives possibles ).

J'ai remarqué que dans Chrome, je peux toujours utiliser les flèches haut / bas pour parcourir la liste ciblée sans problème, mais dans Firefox et IE, ma navigation est interrompue lorsque le focus est censé se déplacer vers le bouton radio sur l'élément caché.

Pour voir cela, procédez comme suit dans cet extrait de code:

1) Dans Firefox ou IE vs Chrome, sélectionnez d'abord le bouton radio # 1 avec la souris ( dans chaque colonne, pour voir chaque approche)

2) Maintenant, utilisez la touche pour naviguer jusqu'à la fin de la liste: voyez que ça casse dans Firefox et IE, mais fonctionne dans Chrome. Le groupe est désélectionné et vous perdez le focus dans Firefox et IE.

3) Vous pouvez également l'essayer depuis la fin dans l'ordre inverse, il se cassera de la même manière.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>

<table>
<tr>
<td>
<span style="font-weight:bold;">With display:none</span>
</td>
<td>
<span style="font-weight:bold;">With visibility:hidden</span>
</td>
<td>
<span style="font-weight:bold;">With position:fixed;opacity:0;</span>
</td>

</tr>
<tr>
<td>

<div>
   <input id="opt1a" type="radio" name="group" value="option1">
   <label for="opt1a">Option 1</label>
</div>
<div>
   <input id="opt2a" type="radio" name="group" value="option2">
   <label for="opt2a">Option 2</label>
</div>
<div>
   <input id="opt3a" type="radio" name="group" value="option3">
   <label for="opt3a">Option 3</label>
</div>
<div style="display:none;">
   <input id="optSecret" type="radio" name="group" value="optionSecret">
   <label for="optSecreta">Secret Option</label>
    
</div>
<div>
   <input id="opt5a" type="radio" name="group" value="option5">
   <label for="opt5a">Option 5</label>
</div>

</td>

<td>
<div>
   <input id="opt1b" type="radio" name="group2" value="option1">
   <label for="opt1b">Option 1</label>
</div>
<div>
   <input id="opt2b" type="radio" name="group2" value="option2">
   <label for="opt2b">Option 2</label>
</div>
<div>
   <input id="opt3b" type="radio" name="group2" value="option3">
   <label for="opt3b">Option 3</label>
</div>
<div style="visibility:hidden;">
   <input id="optSecretb" type="radio" name="group2" value="optionSecret">
   <label for="optSecretb">Secret Option</label>
    
</div>
<div>
   <input id="opt5b" type="radio" name="group2" value="option5">
   <label for="opt5b">Option 5</label>
</div>
</td>

<td>
<div>
   <input id="opt1c" type="radio" name="group3" value="option1">
   <label for="opt1c">Option 1</label>
</div>
<div>
   <input id="opt2c" type="radio" name="group3" value="option2">
   <label for="opt2c">Option 2</label>
</div>
<div>
   <input id="opt3c" type="radio" name="group3" value="option3">
   <label for="opt3c">Option 3</label>
</div>
<div style="position:fixed;opacity:0;">
   <input id="optSecretc" type="radio" name="group3" value="optionSecret">
   <label for="optSecretc">Secret Option</label>
    
</div>
<div>
   <input id="opt5c" type="radio" name="group3" value="option5">
   <label for="opt5c">Option 5</label>
</div>
</td>

</tr>
</table>

Status:

  1. display: none; interrompt le cycle sur le bouton radio masqué, mais réduit l'espace;
  2. visibilité: hidden interrompt le cycle sur le bouton radio masqué, mais préserve l'espace;
  3. position: fixe; opacité: 0 interrompt le cycle une fois (interruption temporaire) mais reprend après avoir appuyé sur la flèche haut / bas pour continuer. Mais le cyclisme normal est toujours cassé.


6 commentaires

des mises à jour à ce sujet? C'est la même situation dans IE, malheureusement


Je ne sais pas pourquoi c'est le cas (j'ai poussé quelques personnes qui le savent peut-être), mais je sais que c'est considéré comme une mauvaise pratique en ce qui concerne A11Y: cacher des éléments de formulaire avec display: none , en partie pour cette même raison. Les solutions dans le duplicata marqué sont la voie à suivre.


Non, les suggestions de ce fil de discussion n'ont pas fonctionné. visibilité: hidden donne le même comportement, uniquement en prenant de la place. position: fixed; opacity: 0; garde le cycle MAIS avec le piège de la perte temporaire dans ce bouton radio, vous perdez donc le focus et devez ensuite appuyer deux fois sur Bas. Je pourrais le montrer si nous pouvions rouvrir le fil. Pourriez-vous supprimer votre désignation "en double" et me permettre de publier plus d'informations, cette question est toujours en suspens.


Vous pouvez toujours modifier la question lorsqu'elle est fermée; Je recommanderais de faire cela en premier.


Merci, j'ai mis à jour ma réponse, vous pouvez voir toutes les options démontrées maintenant - toujours pas de solution. J'ai expliqué le statut.


J'ai rouvert la question et ajusté son titre pour refléter un peu plus directement votre situation. J'espère que vous aurez une solution!


3 Réponses :


2
votes

Je ne l'ai résolu qu'avec une solution de contournement manuelle, où j'intercepte les touches Haut / Bas et le fait sauter par-dessus l'élément caché. Fonctionne dans les 3 navigateurs (FF / IE / Chrome) et s'enroule si nécessaire. Étonnant qu'un piratage soit nécessaire et qu'aucune autre information ne soit disponible nulle part.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>

<div id="container">

  <div>
      <input type="radio" id="opt1" value="1" name="group">
      <label for="opt1">Option 1</label>
  </div>
  <div>
      <input type="radio" id="opt2" value="2" name="group">
      <label for="opt2">Option 2</label>
  </div>  
  <div>
      <input type="radio" id="opt3" value="3" name="group">
      <label for="opt3">Option 3</label>
  </div>  
  <div style="display:none;">
      <input type="radio" id="optSecret" value="secret" name="group">
      <label for="optSecret">Option Secret</label>
  </div>  
  <div>
      <input type="radio" id="opt5" value="5" name="group">
      <label for="opt5">Option 5</label>
  </div>    

</div>

Extrait de démonstration complet

	$('#container').on('keydown', 'input', function(e) {
		
		var groupname = $(this).attr('name');
		var groupindex = $('[name="' + groupname +  '"]').index($(this));
		var groupsize = $('[name="' + groupname + '"]').length;		
		
		// For Down Arrow, if subsequent input in group is hidden, focus the one after it (wrap around if necessary)
		if (e.keyCode == 40 && 
			$('[name="' + groupname + '"]').eq(groupindex + 1).length && 
			$('[name="' + groupname + '"]').eq(groupindex + 1).is(':hidden')) 
		{
			e.preventDefault();
			$('[name="' + groupname + '"]').eq((groupindex + 2) % groupsize).focus();
			$('[name="' + groupname + '"]').eq((groupindex + 2) % groupsize).prop('checked', true);
			$('[name="' + groupname + '"]').trigger('change'); // Trigger Change Event manually for any dependencies
			return false;
		}
		// For Up Arrow, if preceding input in group is hidden, focus and select the one before it (wrap around if necessary)
		else if (e.keyCode == 38 && 
				$('[name="' + groupname + '"]').eq(groupindex - 1).length && 
				$('[name="' + groupname + '"]').eq(groupindex - 1).is(':hidden')) 
		{
			e.preventDefault();
			$('[name="' + groupname + '"]').eq((groupindex - 2) % groupsize).focus();
			$('[name="' + groupname + '"]').eq((groupindex - 2) % groupsize).prop('checked', true);
			$('[name="' + groupname + '"]').trigger('change'); // Trigger Change Event manually for any dependencies
			return false;
		}
		
		return true;
	});
$('#container').on('keydown', 'input', function(e) {

    var groupname = $(this).attr('name');
    var groupindex = $('[name="' + groupname +  '"]').index($(this));
    var groupsize = $('[name="' + groupname + '"]').length;     

    // For Down Arrow, if subsequent input in group is hidden, focus the one after it (wrap around if necessary)
    if (e.keyCode == 40 && 
        $('[name="' + groupname + '"]').eq(groupindex + 1).length && 
        $('[name="' + groupname + '"]').eq(groupindex + 1).is(':hidden')) 
    {
        e.preventDefault();
        $('[name="' + groupname + '"]').eq((groupindex + 2) % groupsize).focus();
        $('[name="' + groupname + '"]').eq((groupindex + 2) % groupsize).prop('checked', true);
        $('[name="' + groupname + '"]').trigger('change'); // Trigger Change Event manually for any dependencies
        return false;
    }
    // For Up Arrow, if preceding input in group is hidden, focus and select the one before it (wrap around if necessary)
    else if (e.keyCode == 38 && 
            $('[name="' + groupname + '"]').eq(groupindex - 1).length && 
            $('[name="' + groupname + '"]').eq(groupindex - 1).is(':hidden')) 
    {
        e.preventDefault();
        $('[name="' + groupname + '"]').eq((groupindex - 2) % groupsize).focus();
        $('[name="' + groupname + '"]').eq((groupindex - 2) % groupsize).prop('checked', true);
        $('[name="' + groupname + '"]').trigger('change'); // Trigger Change Event manually for any dependencies
        return false;
    }

    return true;
});


0 commentaires

1
votes

Pour quiconque rencontre cela et a besoin d'une solution pour sauter plus d'une radio cachée à la fois, comme je l'ai fait, j'ai modifié la réponse acceptée pour permettre de sauter plus d'une radio cachée.

$("#container").on('keydown', 'input', function(e) {

        var groupname = $(this).attr('name');
        var group = $('[name="' + groupname +  '"]:visible');
        var groupindex = group.index($(this));
        var groupsize = group.length;

        // For Down Arrow, if subsequent input in group is hidden, focus the one after it (wrap around if necessary)
        if (e.keyCode == 40) {
            e.preventDefault();
            group.eq((groupindex + 1) % groupsize).focus();
            group.eq((groupindex + 1) % groupsize).prop('checked', true);
            group.eq((groupindex + 1) % groupsize).trigger('change'); // Trigger Change Event manually for any dependencies
            return false;
        }
        // For Up Arrow, if preceding input in group is hidden, focus and select the one before it (wrap around if necessary)
        else if (e.keyCode == 38 && group.eq(groupindex - 1).length) {
            e.preventDefault();
            group.eq((groupindex - 1) % groupsize).focus();
            group.eq((groupindex - 1) % groupsize).prop('checked', true);
            group.eq((groupindex - 1) % groupsize).trigger('change'); // Trigger Change Event manually for any dependencies
            return false;
        }
        return true;
    });

p >


0 commentaires

1
votes

J'ai récemment rencontré ce problème et j'ai compris que si vous définissez l'attribut désactivé sur true sur les boutons radio que vous souhaitez masquer, ainsi que le paramètre d'affichage: aucun, vous pourrez utiliser les touches fléchées haut / bas pour parcourir les boutons radio affichés dans le même groupe de boutons radio sans problème. Cela fonctionne avec Firefox, Chrome et IE 11 (je ne sais pas si cela fonctionnera avec les anciennes versions d'IE).


0 commentaires