用键盘导航模仿JQuery滚动列表框?

时间:2015-03-16 13:39:49

标签: javascript jquery html listbox

我的javascript列表框实现:

$(function() {
    $('#listbox1').on('keydown', function(e) {
        e.preventDefault();
        e.stopImmediatePropagation();
        var $e = $(this).find('.selected');
        switch(e.which) {
            case 38:
                ($e.prev().length) && ($e = $e.removeClass('selected').prev().addClass('selected'));
                $(this).scrollTop( $e.position().top + $(this).scrollTop() );
            break;
            case 40:
                ($e.next().length) && ($e = $e.removeClass('selected').next().addClass('selected'));
                $(this).scrollTop( $e.position().top + $(this).scrollTop() );
            break;
        }
    });
});

这是一个小提琴:http://jsfiddle.net/7qy8p2x1/

有一个真实的列表框和他的模仿。我不这样做,他们使用键盘导航箭头(向上和向下)滚动相同的。真正的列表框在到达最后一个元素之前不会滚动,但模仿会这样做(在每个元素之后)。 ScrollUp工作正常。

请帮我正确实现scrollDown行为。

3 个答案:

答案 0 :(得分:1)

我使用.jspPane滚动列表,但你可以没有jsp(如果你可以使用coffe)可以显示给你.coffee - 它更具可读性。如果你有疑问 - 生病帮助你

var keyboard_control, scroll_to_active;

keyboard_control = function() {
  $('.control-edu').on('keydown', 'input', function(e) {
    var $active, $first, $last, $this, i, temp;
    $this = $(this);
    $active = $('.jspPane span.active');
    $first = $('.jspPane span.opinion').first();
    $last = $('.jspPane span.opinion').last();
    if ($this.closest('.control-edu').find('.options span').length > 1) {
      if (e.keyCode === 38) {
        if ($active.length > 0) {
          if ($active.prev().length > 0) {
            temp = $active.prev();
            $active.removeClass('active');
            temp.addClass('active');
          } else {
            $active.removeClass('active');
            $last.addClass('active');
          }
        } else {
          $last.addClass('active');
        }
        i = $('.jspPane span.active').closest('.control-edu').index();
        scroll_to_active(i, 0);
      } else if (e.keyCode === 40) {
        if ($active.length > 0) {
          if ($active.next().length > 0) {
            temp = $active.next();
            $active.removeClass('active');
            temp.addClass('active');
          } else {
            $active.removeClass('active');
            $first.addClass('active');
          }
        } else {
          $first.addClass('active');
        }
        i = $('.jspPane span.active').closest('.control-edu').index();
        scroll_to_active(i, 1);
      } else if (e.keyCode === 13 && $active.length > 0) {
        $active.click();
      }
    }
  });
};

scroll_to_active = function(i, flag) {
  var $active;
  $active = $('.jspPane span.active');
  if (flag === 1) {
    if (($active.next().length > 0) && ($active.prev().length > 0)) {
      api[i - 1].scrollToElement($active.next());
    } else if ($active.prev().length === 0) {
      api[i - 1].scrollToElement($active);
    } else if ($active.next().length === 0) {
      api[i - 1].scrollToBottom();
    }
  } else if (flag === 0) {
    if ($active.next().length > 0) {
      api[i - 1].scrollToElement($active);
    } else {
      api[i - 1].scrollToBottom();
    }
  } else {
    return

  }
};

编辑:删除js2coffee return

答案 1 :(得分:1)

检查出来

http://jsfiddle.net/7qy8p2x1/1/

$(function() {
$('#listbox1').on('keydown', function(e) {
    e.preventDefault();
    e.stopImmediatePropagation();
    var $e = $(this).find('.selected');
    switch(e.which) {
        case 38:
            ($e.prev().length) && ($e = $e.removeClass('selected').prev().addClass('selected'));
            $(this).scrollTop( $e.position().top + $(this).scrollTop() );
        break;
        case 40:
            ($e.next().length) && ($e = $e.removeClass('selected').next().addClass('selected'));
            $(this).scrollTop( $e.position().top + $(this).scrollTop() );
        break;
    }
});

$('#listbox2').on('keydown', function(e) {
    e.preventDefault();
    e.stopImmediatePropagation();
        var $e = $(this).find(':selected');
    switch(e.which) {
        case 38:
            ($e.prev().length) && ($e = $e.removeClass('selected').prev().addClass('selected'));
            $(this).scrollTop( $e.position().top + $(this).scrollTop() );
        break;
        case 40:
            ($e.next().length) && ($e = $e.removeClass('selected').next().addClass('selected'));
            $(this).scrollTop( $e.position().top + $(this).scrollTop() );
        break;
    }
});  });

答案 2 :(得分:1)

我的解决方案是:

$(function() {
    $('#listbox1').on('keydown', function(e) {
        e.preventDefault();
        e.stopImmediatePropagation();
        var $e = $(this).find('.selected');
        switch(e.which) {
            case 38:
                ($e.prev().length) && ($e = $e.removeClass('selected').prev().addClass('selected'));
                ($e.position().top < 0) && ($(this).scrollTop( $e[0].offsetTop ));
            break;
            case 40:
                ($e.next().length) && ($e = $e.removeClass('selected').next().addClass('selected'));
                ($e.position().top - $(this).height() + $e.height() > 0) && ($(this).scrollTop( $e[0].offsetTop - $(this).height() + $e.outerHeight() ));
            break;
        }
    });
});

http://jsfiddle.net/7qy8p2x1/7/

跨浏览器(但解决方法)解决方案:

http://jsfiddle.net/7qy8p2x1/4/