以编程方式滚动表格行

时间:2017-03-16 05:36:00

标签: angularjs

this plunk的目标是有一个表格,其中上下键将用于以编程方式选择行并滚动表格。选定的行将具有不同的背景颜色。

在键入/关闭时,我使用e.preventDefault()来避免行向上/向下移动两次。问题是当我开始向下滚动时,行保持固定并且所选行消失。如何解决这个问题?

HTML

<div id="selector" tabindex="0" ng-keydown="scroll($event)"
          style="width:300px;height:80px;border:1px solid gray;overflow-y:auto">
     <table>
        <tr ng-repeat="item in items">
            <td class="td1" ng-class="{'tdactive' : $index==index }">{{item.col}}</td>
            <td class="td1" ng-class="{'tdactive' : $index==index }">{{item.dsc}}</td>
        </tr>
     </table>
 </div>

的Javascript

var app = angular.module('app', []);

app.controller('ctl', function($scope) {

  document.getElementById("selector").focus();

  $scope.items = [ {col:"aaa", dsc:"AAA1"}, {col:"bbb", dsc:"BBB2"} , {col:"ccc", dsc:"CCC3"}, 
            {col:"aaa2", dsc:"AAA21"}, {col:"bbb2", dsc:"BBB22"} , {col:"ccc2", dsc:"CCC23"}, 
            {col:"aaa2", dsc:"AAA21"}, {col:"bbb2", dsc:"BBB22"} , {col:"ccc2", dsc:"CCC23"} ];
  $scope.index = 0;

  $scope.scroll = function(e) {
      if (e.which === 40) { // down arrow
          if ($scope.index<$scope.items.length - 1)
              $scope.index++;
          e.preventDefault();
      }
      else if (e.which === 38) { // up arrow
          if ($scope.index>0)
              $scope.index--;
          e.preventDefault();
      }
  };
});

1 个答案:

答案 0 :(得分:4)

首先,您需要将表格行ID添加为id="tr-{{$index}}"

如果tr在当前视口中

,则可以阻止滚动
$scope.scroll = function(e) {
    var parentContainer = document.getElementById("selector");
      if (e.which === 40) { // down arrow
          if ($scope.index<$scope.items.length - 1)
          {

          var element = document.getElementById("tr-"+$scope.index);
          if(isElementInViewport(parentContainer,element)){
            e.preventDefault();
          }

              $scope.index++;
          }
      }
      else if (e.which === 38) { // up arrow
          if ($scope.index>0)
          {
          var element = document.getElementById("tr-"+$scope.index);
          if(!isElementInViewport(parentContainer,element)){
            e.preventDefault();
          }
              $scope.index--;
          }
      }
  };

function isElementInViewport(parent, el) {
  if(parent==undefined || el==undefined)
  return false;
    var elRect = el.getBoundingClientRect(),
        parRect = parent.getBoundingClientRect();
        //console.log(elRect)
        //console.log(parRect)
        var elementHeight = elRect.height;
    return (
        elRect.top >= parRect.top &&
        elRect.bottom <= parRect.bottom &&
        elRect.bottom+elementHeight<= parRect.bottom
    );
}

Working Plunker