0

I am trying to implement a mechanism where specific items on a screen are navigable using arrows keys.

At the moment, I am drawing a red box around items as they move and pressing enter activates them.

I have the following directive: (credits here and here)

.directive("moveNext", function() {
    return {
        restrict: "A",
        link: function($scope, element,attrs) {
            element.bind("keyup", function(e) {
                if (e.which == 37) {         
                  console.log ("MOVE LEFT:" + JSON.stringify(element));   
                  element[0].classList.remove('selected');
                  var partsId = attrs.id.match(/move-(\d+)/);
                  console.log ("CURRENT PARTS="+JSON.stringify(partsId));
                  var currentId = parseInt(partsId[1]);

                  console.log ("Looking for move-"+(currentId-1));
                  var nextElement = angular.element(document.querySelectorAll('#move-' + (currentId - 1)));
                   // var $nextElement = element.next().find('movehere');
                    if(nextElement.length) {
                      nextElement[0].classList.add('selected');
                        nextElement[0].focus();
                       // $nextElement[0].style.border='5px solid red';;
                    }
                }

                if (e.which == 39) {         
                  console.log ("MOVE RIGHT:" + JSON.stringify(element));   
                  element[0].classList.remove('selected');
                  var partsId = attrs.id.match(/move-(\d+)/);
                  var currentId = parseInt(partsId[1]);
                  console.log ("CURRENT PARTS="+JSON.stringify(partsId));
                  var currentId = parseInt(partsId[1]);


                  var nextElement = angular.element(document.querySelectorAll('#move-' + (currentId + 1)));


                  console.log ("Looking for move-"+(currentId+1));
                   // var $nextElement = element.next().find('movehere');
                    if(nextElement.length) {
                      nextElement[0].classList.add('selected');
                        nextElement[0].focus();
                       // $nextElement[0].style.border='5px solid red';;
                    }
                }

                if (e.which == 13) {                

                  console.log ("ENTER:" + JSON.stringify(element)); 
                   //  element.triggerHandler('click');

                }
            });
            if (event) event.preventDefault();
        }
    }
})         

And then in the template I have the following, for example:

<div>
  <button move-next id="move-1" ng-click="d1()">Yes</button>
  <button move-next id="move-3" ng-click="d1()">Yes</button>
  <button  ng-click="d1()">No</button>
  <button move-next id="move-2" ng-click="d1()">Yes</button>
</div>
<a href="d2()" move-next id="move-4">Yes</a> <!-- PROBLEM -->
<a href="d2()" move-next id="move-5">Yes</a> <!-- NEVER COMES HERE -->

The nice part is I can now navigate to any "clickable" element depending on the ID order I set, which is my intention. The problem is that focus() only works on items that are focusable, so once "move-4" is highlighted by the directive, the focus() doesn't really work so I can never move "next" to "move-5"

thanks

4

1 回答 1

0

问题解决了:

  1. 我删除了指令,而是写了一个全局 keyUpHandler
  2. 在 keyup 处理程序中,我保留了最后选择的项目 ID 的状态,因此无论项目是否可聚焦,我都可以 +- 它。

我现在可以使用方向键在任何视图上导航任意项目。

然而,问题是 move-Ids 在视图中必须是唯一的,否则我需要找到一种方法来仅在活动视图上进行查询。我需要弄清楚如何做到这一点。currentView = document.querySelector('ion-view[nav-view="active"]');不起作用。

代码(需要清理,但似乎工作)

window.addEventListener('keyup', keyUpHandler, true);

      function keyUpHandler(evt){

        $timeout (function() {

          var currentView = document.querySelector('ion-view[nav-view="active"]');
          var keyCode=evt.keyCode;
          var el, nextel;

          if (keyCode == 13 ) {

            if ($rootScope.dpadId >0) {
               el = angular.element(currentView.querySelector('#move-' +$rootScope.dpadId));
              el.triggerHandler('click'); 
            }

            return;
          }

          if (keyCode == 37 || keyCode == 39) {  

            if ($rootScope.dpadId < 1) { 
              console.log ("First dpad usage");
              $rootScope.dpadId = 1; 
              el = angular.element(currentView.querySelector('#move-1'));
              if (el.length) {
                el[0].classList.add('selected');
              }

            } else {
              // unselect old
               el = angular.element(currentView.querySelector('#move-' +$rootScope.dpadId));

               var nextId = (keyCode == 37) ? $rootScope.dpadId -1: $rootScope.dpadId + 1;

               nextel = angular.element(currentView.querySelector('#move-' +nextId));

              if (nextel.length) {
                el[0].classList.remove('selected');
                nextel[0].classList.add('selected');
                $rootScope.dpadId = nextId;
              }


              console.log ("dpadID="+$rootScope.dpadId);

            }
          }

        });
     }
于 2018-05-13T16:09:14.500 回答