为什么使用键盘键导航时滚动无法正常工作

时间:2019-03-09 17:18:39

标签: javascript jquery html css

我在使用键盘上/下

滚动时遇到问题

如何复制:只需使用键盘上的up/down箭头,观察selected被隐藏。我滚动无法正常工作。

问题:如何使selected行始终可见。

请查看代码笔演示以获得完整视图: https://codepen.io/anon/pen/ZPypBM

$(function(){
    var li = $('.rtable tbody tr');
    var liSelected;
    $(window).keydown(function(e){
    
        if(e.which === 40){
            if(liSelected){
                liSelected.removeClass('selected');
                next = liSelected.next();
                if(next.length > 0){
                    liSelected = next.addClass('selected');
                }else{
                    liSelected = li.eq(0).addClass('selected');
                }
            }else{
                liSelected = li.eq(0).addClass('selected');
            }
        }else if(e.which === 38){
            if(liSelected){
                liSelected.removeClass('selected');
                next = liSelected.prev();
                if(next.length > 0){
                    liSelected = next.addClass('selected');
                }else{
                    liSelected = li.last().addClass('selected');
                }
            }else{
                liSelected = li.last().addClass('selected');
            }
        }
    });
});
.selected{
    background:red;
}

#table_wrapper{
    width: 464px;
    background: #d9d5dc;
    padding: 30px;
    height: 126px;
    overflow-y: auto;;
}


.rtable {
  /*!
  // IE needs inline-block to position scrolling shadows otherwise use:
  // display: block;
  // max-width: min-content;
  */
  background: #dde4f9 !important;
  display: inline-block;
  vertical-align: top;
  max-width: 100%;
  
  overflow-x: auto;
  
  // optional - looks better for small cell values
  white-space: nowrap;

  border-collapse: collapse;
  border-spacing: 0;
}

.rtable,
.rtable--flip tbody {
  // optional - enable iOS momentum scrolling
  -webkit-overflow-scrolling: touch;
  
  // scrolling shadows
  background: radial-gradient(left, ellipse, rgba(0,0,0, .2) 0%, rgba(0,0,0, 0) 75%) 0 center,
              radial-gradient(right, ellipse, rgba(0,0,0, .2) 0%, rgba(0,0,0, 0) 75%) 100% center;
  background-size: 10px 100%, 10px 100%;
  background-attachment: scroll, scroll;
  background-repeat: no-repeat;
}

// change these gradients from white to your background colour if it differs
// gradient on the first cells to hide the left shadow
.rtable td:first-child,
.rtable--flip tbody tr:first-child {
  background-image: linear-gradient(to right, rgba(255,255,255, 1) 50%, rgba(255,255,255, 0) 100%);
  background-repeat: no-repeat;
  background-size: 20px 100%;
}

// gradient on the last cells to hide the right shadow
.rtable td:last-child,
.rtable--flip tbody tr:last-child {
  background-image: linear-gradient(to left, rgba(255,255,255, 1) 50%, rgba(255,255,255, 0) 100%);
  background-repeat: no-repeat;
  background-position: 100% 0;
  background-size: 20px 100%;
}

.rtable th {
  font-size: 11px;
  text-align: left;
  text-transform: uppercase;
  background: #f2f0e6;
}

.rtable th,
.rtable td {
  padding: 6px 12px;
  border: 1px solid #d9d7ce;
}

.rtable--flip {
  display: flex;
  overflow: hidden;
  background: none;
}

.rtable--flip thead {
  display: flex;
  flex-shrink: 0;
  min-width: min-content;
}

.rtable--flip tbody {
  display: flex;
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;
}

.rtable--flip tr {
  display: flex;
  flex-direction: column;
  min-width: min-content;
  flex-shrink: 0;
}

.rtable--flip td,
.rtable--flip th {
  display: block;
}

.rtable--flip td {
  background-image: none !important;
  // border-collapse is no longer active
  border-left: 0;
}

// border-collapse is no longer active
.rtable--flip th:not(:last-child),
.rtable--flip td:not(:last-child) {
  border-bottom: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="table_wrapper">

<table class="rtable">
  <thead>
    <tr>
      <th>Browser</th>
      <th>Sessions</th>
      <th>Percentage</td>
      <th>New Users</th>
      <th>Avg. Duration</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Chrome</td>
      <td>9,562</td>
      <td>68.81%</td>
      <td>7,895</td>
      <td>01:07</td>
    </tr>
    <tr>
      <td>Firefox</td>
      <td>2,403</td>
      <td>17.29%</td>
      <td>2,046</td>
      <td>00:59</td>
    </tr>
    <tr>
      <td>Safari</td>
      <td>1,089</td>
      <td>2.63%</td>
      <td>904</td>
      <td>00:59</td>
    </tr>
    <tr>
      <td>Internet Explorer</td>
      <td>366</td>
      <td>2.63%</td>
      <td>333</td>
      <td>01:01</td>
    </tr>
    <tr>
      <td>Safari (in-app)</td>
      <td>162</td>
      <td>1.17%</td>
      <td>112</td>
      <td>00:58</td>
    </tr>
    <tr>
      <td>Opera</td>
      <td>103</td>
      <td>0.74%</td>
      <td>87</td>
      <td>01:22</td>
    </tr>
    <tr>
      <td>Edge</td>
      <td>98</td>
      <td>0.71%</td>
      <td>69</td>
      <td>01:18</td>
    </tr>
    <tr>
      <td>Other</td>
      <td>275</td>
      <td>6.02%</td>
      <td>90</td>
      <td>N/A</td>
    </tr>
  </tbody>
</table>

</div>

1 个答案:

答案 0 :(得分:1)

我已经对您的代码进行了重组,现在您可以按需运行它了。

在最后一个元素上按下down_arrow后,应滚动到第一个元素。对于up_arrow

使用以下方法更改您的js代码:

$(function(){
    var li = $('.rtable tbody tr');
    var liSelected;
    var index = -1;
    var move = function() {
      liSelected = li.eq(index);
      li.removeClass('selected');
      liSelected.addClass('selected'); 
    }
    var scrollToSelected = function() {
      $('#table_wrapper').animate({
          scrollTop: liSelected.offset().top
      }, 150);
    }
    $(window).keydown(function(e){
      if (e.which === 40) {
        if (index == -1) {
          index = 0;
          move();
        } else {
          index = (index + 1) % li.length;
          if (index == 0) {
            move();
            scrollToSelected();
          }
          move();
        }        
      } else if(e.which == 38) {
        index -= 1;
        if (index < 0) {
          index = li.length -1;
          move();
          scrollToSelected();
        } else {
          move();
        }
      }
    });  
});

并且您应该使用未压缩的jquery版本进行滚动动画。

只需从您的jquery脚本标记中删除.min

更新:

如果要使用自己的代码,则必须应用相同的逻辑。当所选元素从第一个到最后一个或从最后一个到第一个时,滚动到元素。 我已将此方法添加到您的代码中以滚动元素。

var scrollToSelected = function() {
    $("#table_wrapper").animate(
      { scrollTop: liSelected.offset().top },
      150
    );
  };

并在2个地方使用了该方法。

$(function() {
  var li = $(".rtable tbody tr");
  var liSelected;
  var scrollToSelected = function() {
    $("#table_wrapper").animate(
      {
        scrollTop: liSelected.offset().top
      },
      150
    );
  };
  $(window).keydown(function(e) {
    if (e.which === 40) {
      if (liSelected) {
        liSelected.removeClass("selected");
        next = liSelected.next();
        if (next.length > 0) {
          liSelected = next.addClass("selected");
        } else {
          liSelected = li.eq(0).addClass("selected");
          scrollToSelected(); // first
        }
      } else {
        liSelected = li.eq(0).addClass("selected");
      }
    } else if (e.which === 38) {
      if (liSelected) {
        liSelected.removeClass("selected");
        next = liSelected.prev();
        if (next.length > 0) {
          liSelected = next.addClass("selected");
        } else {
          liSelected = li.last().addClass("selected");
          scrollToSelected(); // second
        }
      } else {
        liSelected = li.last().addClass("selected");
      }
    }
  });
});