Как сохранить выбранный LI видимым (не скрытым)?

Я использую jQuery 1.12. У меня есть стиль UL с элементами LI. Я использую приведенный ниже код, чтобы выбрать эти элементы, используя стрелки вверх или вниз на клавиатуре, когда DIV имеет фокус...

 $(".select").bind('keydown', function(event) {
    var currentElement = $(this).find(".select-options li.selected");
    if (currentElement.length == 0) {
        currentElement = $(this).find(".select-options li")[0];
      $(currentElement).addClass("selected");
      return;
    }       // if
    var nextElement;
    switch(event.keyCode){
    // case up
    case 38:
        nextElement = $(this).find(".select-options li")[($(this).find(".select-options li").index(currentElement) - 1) % $(this).find(".select-options li").length];
        break;
    case 40:
        nextElement = $(this).find(".select-options li")[($(this).find(".select-options li").index(currentElement) + 1) % $(this).find(".select-options li").length];
      break;
    }
    $(this).find(".select-options li").removeClass("selected");
    if(nextElement !== null) {
        $(nextElement).addClass("selected");
    }
 });

Проблема заключается в том, что если вы постоянно нажимаете клавишу "вниз" (например), в конечном итоге вы не сможете увидеть выбранный элемент. Как настроить параметры так, чтобы выбранный элемент всегда был видимым? Скрипт, иллюстрирующий проблему, находится здесь - http://jsfiddle.net/sge8g5qu/1/.

Ответ 1

В конце, где вы добавляете класс к вызову nextElement .scrollIntoView( false ) на нем.

if(nextElement !== null) {
    $(nextElement).addClass("selected");
    nextElement.scrollIntoView(false); // added this line
}

Обновлен скрипт: http://jsfiddle.net/gaby/6fjnnu55/

Ответ 2

Вы можете использовать .offset(), чтобы найти верхнее смещение вашего окна выбора и выбранного элемента.

Затем вы можете использовать .scrollTop, попробуйте что-то вроде:

var yourSelectInput = $('.select');

var nextElementTop = $(nextElement).offset().top;  // get offset of element
var selectTop = yourSelectInput.offset().top;  // get offset of select input

// set the scrollTop to the scroll input offset
// plus the difference of the option top offset
yourSelectInput.scrollTop(yourSelectInput.scrollTop() + (nextElementTop - selectTop));

Ответ 3

Самый простой способ добиться этого - сделать акцент на элементе li с помощью tabIndex="0".

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

См. фрагмент ниже.

$('.select-options li').on('keydown', function (e) {
  var key = e.which || e.keyCode;
  var nextElement = false;
  
  switch (key) {
    case 38: //Up
      nextElement = $(this).prev().length ? $(this).prev() : $(this).parent().find('li').last();
      break;
    case 40:
      nextElement = $(this).next().length ? $(this).next() : $(this).parent().find('li').first();
      break;
  };
   
  if (nextElement) {
    e.preventDefault();
     
    $('.selected').removeClass('selected');
    nextElement.addClass('selected').focus();
    
    console.log(nextElement);
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="select-options">
  <li tabindex="0">Option 1</li>
  <li tabindex="0">Option 2</li>
  <li tabindex="0">Option 3</li>
  <li tabindex="0">Option 4</li>
  <li tabindex="0">Option 5</li>
  <li tabindex="0">Option 6</li>
  <li tabindex="0">Option 7</li>
  <li tabindex="0">Option 8</li>
  <li tabindex="0">Option 9</li>
  <li tabindex="0">Option 10</li>
  <li tabindex="0">Option 11</li>
  <li tabindex="0">Option 12</li>
  <li tabindex="0">Option 13</li>
  <li tabindex="0">Option 14</li>
  <li tabindex="0">Option 15</li>
  <li tabindex="0">Option 16</li>
  <li tabindex="0">Option 17</li>
  <li tabindex="0">Option 18</li>
  <li tabindex="0">Option 19</li>
  <li tabindex="0">Option 20</li>
</ul>