Установка фокуса на выбранный элемент с помощью Javascript прокручивает первый элемент вне поля зрения

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

<select id="multiSelect" size="3" multiple>
  <option value="item1">Item 1</option>
  <option value="item2">Item 2</option>
  <option value="item3">Item 3</option>
  <option value="item4">Item 4</option>
  <option value="item5">Item 5</option>
  <option value="item6">Item 6</option>
</select>

Я хочу разрешить пользователю вводить значения в текстовый ввод выше, а затем использовать их «стрелку вниз», чтобы перейти к результатам, которые появятся в поле выбора.

inputField.addEventListener("keydown", function(e) {
  if (e.keyCode == 40) {
    multiSelect.focus();
    multiSelect.selectedIndex = 0;
  }
});

Когда пользователь делает это, первый элемент в поле множественного выбора прокручивается вне поля зрения. Эта проблема возникает как в Chrome, так и в Firefox (на Mac [Safari в порядке]).

Вы можете увидеть проблему здесь.

https://jsfiddle.net/rsturim/ops9q3xk/


person rsturim    schedule 05.04.2016    source источник


Ответы (1)


Добавьте preventDefault к вашему ключевому событию. Я заметил, что в Safari, например, он немного прокручивает страницу, если может. Это означает, что ключевое событие фактически передается нескольким вещам, которые могут включать ваш выбор:

var inputField = document.getElementById("inputField");
var multiSelect = document.getElementById("multiSelect");

inputField.addEventListener("keydown", function(e) {
  if (e.keyCode == 40) {
    e.preventDefault();
    multiSelect.focus();
    multiSelect.selectedIndex = 0;
  }
});

multiSelect.addEventListener("keydown", function(e) {
  if (e.keyCode == 38 && multiSelect.selectedIndex == 0) {
    inputField.focus();
  }
});
<div>
  <input id="inputField" type="text" placeholder="start here" /> => use down arrow to move to multi-select box
</div>
<div>
  <select id="multiSelect" size="5" multiple>
    <option value="item1">Item 1</option>
    <option value="item2">Item 2</option>
    <option value="item3">Item 3</option>
    <option value="item4">Item 4</option>
    <option value="item5">Item 5</option>
    <option value="item6">Item 6</option>
    <option value="item7">Item 7</option>
    <option value="item8">Item 8</option>
    <option value="item9">Item 9</option>
    <option value="item10">Item 10</option>
  </select> => use up arrow to move to input box
</div>

Кроме того, обратите внимание, что элемент input является самозакрывающимся элементом, поэтому <input />, а не <input></input> (извините, редактор фрагмента SO показал мне семантическую ошибку) (проверено в Safari и Chrome)

person somethinghere    schedule 05.04.2016
comment
Вау, вот и все. Отличная находка, очень признательна! - person rsturim; 05.04.2016