AngularJS / ionic: навигация по конкретным элементам экрана с помощью клавиш со стрелками - PullRequest
0 голосов
/ 13 мая 2018

Я пытаюсь реализовать механизм, в котором определенные элементы на экране можно перемещать с помощью клавиш со стрелками.

В данный момент я рисую красную рамку вокруг предметов, когда они движутся, и нажатие Enter активирует их.

У меня есть следующая директива: (кредиты здесь и здесь )

.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();
        }
    }
})         

И тогда в шаблоне у меня есть следующее, например:

<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 -->

Приятно то, что теперь я могу переходить к любому «активируемому» элементу в зависимости от установленного мной порядка идентификаторов, что и является моим намерением. Проблема состоит в том, что focus() работает только с элементами, которые могут быть сфокусированы, поэтому, как только директива подсвечивает «move-4», focus() действительно не работает, поэтому я никогда не могу двигаться дальше "на" ход-5 "

спасибо

1 Ответ

0 голосов
/ 13 мая 2018

Проблема решена:

  1. Я удалил директиву и вместо этого написал глобальный keyUpHandler
  2. Внутри обработчика keyup я сохранил состояние последнего выбранного элемента ID, чтобы я мог +- независимо от того, является ли объект фокусируемым или нет.

Теперь я могу перемещаться по произвольным элементам в любом виде с помощью навигационной панели.

Проблема, однако, в том, что идентификаторы перемещения должны быть уникальными для разных представлений, или мне нужно найти способ сделать запрос только в активном представлении.Мне нужно выяснить, как это сделать.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);

            }
          }

        });
     }
...