Как пропустить скрытый вариант радио с клавиатурной навигацией в Firefox и IE? - PullRequest
0 голосов
/ 21 января 2019

ОБНОВЛЕНИЕ Следующая проблема возникает даже после опробования предложений здесь .В последнем фрагменте кода демонстрируются все 3 подхода скрытия радиокнопки и прерывания навигации по клавиатуре / (клавиши со стрелками вверх / вниз) в группе радиостанций в Firefox и IE.


Предположим, у меня есть радиогруппа, каждая радиокнопка с меткой в ​​DIV.Я использую клавиши со стрелками (вверх / вниз), чтобы просматривать мои радиокнопки, когда хотя бы одна из них имеет фокус.

Одна из радиокнопок в моей радиогруппе скрыта.Он находится в DIV, в котором есть display:none; (но я также попытался visibility:hidden и position:fixed;opacity:0 в качестве возможных альтернатив).

Я заметил, что в Chrome я все еще могу использовать стрелки вверх / вниз для перемещения посфокусированный список без проблем, но в Firefox и IE моя навигация прерывается, когда фокус должен сместиться на радиокнопку поверх скрытой.

Чтобы увидеть это, выполните в этом фрагменте следующее:

1) В Firefox или IE против Chrome сначала выберите переключатель 1 с помощью мыши (в каждом столбце, чтобы увидеть каждый подход)

2) Теперь используйте клавишу , чтобыперейдите в конец списка: посмотрите, что он ломается в Firefox и IE, но работает в Chrome.Отмена выбора группы, и вы теряете фокус в Firefox и IE.

3) Вы также можете попробовать ее с конца в обратном порядке, она также сломается.

<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>

Статус:

  1. display:none; прерывает цикл над скрытой переключателем, но сокращает пробел;
  2. visibility:hidden прерывает цикл над скрытым переключателем, но сохраняет пробел;
  3. position:fixed;opacity:0 прерывает цикл один раз (временная ловушка), но затем возобновляется после нажатия стрелок вверх / вниз для продолжения,Но нормальная езда на велосипеде все еще нарушена.

Ответы [ 2 ]

0 голосов
/ 24 марта 2019

Кому бы ни приходилось сталкиваться с этим и ему нужно решение для пропуска более одного скрытого радио за раз, как я это сделал, я изменил принятый ответ, чтобы учесть пропуск нескольких скрытых радио.

$("#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;
    });
0 голосов
/ 28 января 2019

Я решил это только с помощью ручной работы, где я перехватывал клавиши «Вверх» и «Вниз» и заставлял его перепрыгивать через скрытый элемент.Работает во всех 3 браузерах (FF / IE / Chrome) и при необходимости оборачивается.Удивительно, что требуется взлом, и никакая другая информация нигде не доступна.

$('#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;
	});
<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>
...