Запретить браузеру повторно позиционировать сфокусированные элементы, к которым можно перейти с помощью вкладок

Когда вы перемещаетесь по элементам формы или привязкам с помощью клавиши табуляции (и Shift + Tab), браузер автоматически прокручивается до этого выделенного элемента. Если элемент недоступен для просмотра, потому что он является частью переполненного содержимого, где переполнение настроено как скрытое, он перемещает (или прокручивает) контейнер содержимого, чтобы показать элемент, находящийся в фокусе. Я хочу либо остановить, либо найти способ свести на нет такое поведение

Вот что я собрал, чтобы продемонстрировать проблему. Я воспроизвел это в Chrome.

https://jsfiddle.net/charlieko/wLy7vurj/2/

var container = $("#container")
var cur = 0;

function go(increment) {
  var next = cur + increment;
  if (next < 0) next = 4;
  else if (next > 4) next = 0;
  cur = next
  var newX = cur * 500;
  container.css({
    transform: 'translate(-' + newX + 'px, 0)'
  })
}

$("#left").click(function(e) {
  go(-1);
});
$("#right").click(function(e) {
  go(1);
});
body {
  overflow: hidden;
}
#container {
  width: 2600px;
  overflow: none;
  transition: transform 0.4s;
  transform: translate(0, 0);
  overflow: hidden;
  margin: 0;
}
li {
  width: 500px;
  text-align: center;
  list-style-type: none;
  float: left;
  margin: 0;
  padding: 0;
}
a {
  color: black;
  font-size: 2.0rem;
}
#ui {
  position: fixed;
  top: 200px;
}
#ui span {
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
  <ul>
    <li><a href="#">Link 1</a> | ABCD EFG</li>
    <li><a href="#">Link 2</a> | HIJK LMNO</li>
    <li><a href="#">Link 3</a> | PQRSTU VW</li>
    <li><a href="#">Link 4</a> | XYZA BC</li>
    <li><a href="#">Link 5</a> | DEFG HI</li>
  </ul>
</div>
<div id="ui">
  <div>
    <span id="left">Left</span>
    |
    <span id="right">Right</span>
  </div>
  <p>
    Use left and right to move. Issue: Use tab key (and shift+tab) to navigate to any of the links. The container of the links shift to show the focused link. Notice the content is decentered when it happens.
  </p>
</div>

Проблема в том, что теперь есть два способа перемещать содержимое: с помощью кнопок «влево» и «вправо» и с помощью табуляции по ссылкам. Когда пользователь выбирает навигацию с помощью вкладок, это портит логику скольжения. Содержимое децентрировано, и индекс, который я сохранил в переменной, больше не представляет то, что видно на экране. Я могу решить проблему доступности программно, используя событие onFocus, так что это автоматическое поведение ничему не помогает.

Есть ли способ остановить это поведение? Я уже пробовал метод preventDefault() для событий onFocus на элементах привязки.


person CTheDark    schedule 05.04.2016    source источник
comment
почему вы физически перемещаете элементы, почему бы вам просто не анимировать их скольжение, а затем просто скрыть?   -  person johnny 5    schedule 05.04.2016
comment
Я хочу, чтобы пользователи использовали клавишу табуляции для навигации. Сокрытие этого помешало бы этому, верно? Я просто хочу, чтобы навигация по табуляции не перемещала контейнер, в котором находится сфокусированный элемент, что портит настроенную мной логику.   -  person CTheDark    schedule 05.04.2016


Ответы (4)


Я смог найти решение. Что делает браузер, так это то, что он прокручивает прямой родительский элемент переполненного содержимого до позиции, в которой сфокусированный элемент находится прямо в центре. Простое изменение свойства scrollLeft родительского элемента помогло. Итак, в событии onFocus ссылки:

function onFocus (e) {
    document.getElementById('content-parent').scrollLeft = 0;
    // Code for repositioning the content itself using transform with transition animation
}
person CTheDark    schedule 13.04.2016
comment
Это по-прежнему позволит отображать элемент на вкладке, просто браузер не покажет, что он это сделал. Это, вероятно, приведет к тому, что люди, которые используют клавишу табуляции для навигации по странице, будут разочарованы количеством табуляции, необходимой для перехода к следующему элементу после этого виджета. - person Eric; 24.03.2017

Overflow:hidden обычно подходит для контента, предназначенного для прокрутки и перемещения, поэтому предотвратить это будет сложно. Если вы хотите, чтобы элемент управления Tab оставался только на видимых вещах (включая любые кнопки или ссылки, которые обновляют ваш ползунок), вам потребуется другой метод скрытия содержимого в дополнение к переполнению (или вместо него).

Попробуйте display:none в элементах вашего списка, пока они не окажутся в открытой/видимой части div#container. Это удаляет их из DOM (и, следовательно, из фокуса клавиатуры), пока вы не будете готовы. Если вы создаете класс с именем 'hidden', содержащий в нем только display:none, то единственный сценарий, который вам понадобится, - это добавить/удалить класс из элемента списка, когда используются элементы управления Left/Right. Я бы отредактировал ваш пример кода для демонстрации, но сейчас я на крошечном экране.

Проблема в том, что пользователи вашей клавиатуры не могут добраться до элементов управления «Влево/Вправо». Если вы измените их на элементы кнопок или ссылок, то они будут иметь поддержку клавиатуры по умолчанию в каждом браузере. И тогда все ваши пользователи полагаются на ваши элементы управления «Влево/Вправо», независимо от того, используют ли они мышь или клавиатуру, что дает вам больше контроля над тем, как это выглядит на каждом этапе.

person stringy    schedule 07.04.2016
comment
Я думаю, что это хороший ответ, учитывая мой код jsfiddle и мой вопрос. Я не смог реализовать это решение, потому что фактическое приложение, над которым я работаю, имеет особый дизайн, в котором на самом деле нет постоянных кнопок влево/вправо. - person CTheDark; 13.04.2016

Вы можете просто установить tabindex to -1 для ссылок, чтобы избежать фокусировки.

person Chetan    schedule 07.04.2016
comment
Я по-прежнему хочу, чтобы пользователи могли перемещаться с помощью клавиши табуляции. - person CTheDark; 07.04.2016

Вы можете установить tabindex="-1" для элементов, которые находятся за пределами экрана. Это предлагается MDN.

https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex

person Antfish    schedule 18.04.2018