2013-05-31 4 views
12

Рассмотрим следующую разметку -Navigate интерфейс с помощью клавиатуры

<ul id="list"> 
    <li class="list-item" tabindex="0">test 1</li> 
    <li class="list-item" tabindex="1">test 2</li> 
    <li class="list-item" tabindex="2">test 3</li> 
    <li class="list-item" tabindex="3">test 4</li> 
    <li class="list-item" tabindex="4">test 5</li> 
    <li class="list-item" tabindex="5">test 6</li> 
    <li class="list-item" tabindex="6">test 7</li> 
</ul> 

и этот кусок кода JQuery -

$(".list-item").bind({ 
    keydown: function(e) { 
     var key = e.keyCode; 
     var target = $(e.currentTarget); 

     switch(key) { 
      case 38: // arrow up 
       target.prev().focus(); 
       break; 
      case 40: // arrow down 
       target.next().focus(); 
       break; 
     } 
    }, 

    focusin: function(e) { 
     $(e.currentTarget).addClass("selected"); 
    }, 

    focusout: function(e) { 
     $(e.currentTarget).removeClass("selected"); 
    } 
}); 
$("li").first().focus(); 

Как я порт этот код в угловой? У меня это до сих пор -

<li class="list-item" ng-repeat="item in items" tabindex="{{item.tabIndex}}"> 
         {{item.name}} 
        </li> 

Как сделать привязку в угловом?

+0

Спасибо. Я уже смотрю на них. Я новичок в том, что углы, поэтому обертывание головы вокруг директив является сложной задачей. – tempid

+0

[Ответ в этой теме] (http://stackoverflow.com/questions/15044494/what-is-angularjs-way-to-create-global-keyboard-shortcuts) использует описанный выше метод для захвата ключевых событий. – rGil

+0

Возможный дубликат [Перемещение по пользовательскому интерфейсу с использованием только клавиатуры] (http://stackoverflow.com/questions/17388021/navigate-the-ui-using-only-keyboard) –

ответ

11

Лучший способ, я думаю, использовать tabindex, чтобы найти элементы для фокусировки. Попробуй что-нибудь вроде этого;

<li class="list-item" ng-repeat="item in items" 
    tabindex="{{item.tabIndex}}" 
    ng-class="item.selected" 
    ng-keydown="onKeydown(item, $event)" ng-focus="onFocus(item)">{{item.name}} 
</li> 

Затем в вашем контроллере вы хотите обработчик Keydown;

var KeyCodes = { 
    BACKSPACE : 8, 
    TABKEY : 9, 
    RETURNKEY : 13, 
    ESCAPE : 27, 
    SPACEBAR : 32, 
    LEFTARROW : 37, 
    UPARROW : 38, 
    RIGHTARROW : 39, 
    DOWNARROW : 40, 
}; 

$scope.onKeydown = function(item, $event) { 
     var e = $event; 
     var $target = $(e.target); 
     var nextTab; 
     switch (e.keyCode) { 
      case KeyCodes.ESCAPE: 
       $target.blur(); 
       break; 
      case KeyCodes.UPARROW: 
       nextTab = - 1; 
       break; 
      case KeyCodes.RETURNKEY: e.preventDefault(); 
      case KeyCodes.DOWNARROW: 
       nextTab = 1; 
       break; 
     } 
     if (nextTab != undefined) { 
      // do this outside the current $digest cycle 
      // focus the next element by tabindex 
      $timeout(() => $('[tabindex=' + (parseInt($target.attr("tabindex")) + nextTab) + ']').focus()); 
     } 
}; 

И простой в использовании обработчик фокуса;

$scope.onFocus = function(item, $event) { 
    // clear all other items 
    angular.forEach(items, function(item) { 
     item.selected = undefined; 
    }); 

    // select this one 
    item.selected = "selected"; 
}; 

Это не в моей голове, на случай, если кто-нибудь встретит эту нить, как я.

9

Вы также можете создать угловую директиву, как показано ниже:

claimApp.directive('keyNavigation', function ($timeout) { 
    return function (scope, element, attrs) { 
     element.bind("keydown keypress", function (event) { 
      if (event.which === 38) { 
       var target = $(event.target).prev(); 
       $(target).trigger('focus'); 
      } 
      if (event.which === 40) { 
       var target = $(event.target).next(); 
       $(target).trigger('focus'); 
      } 
     }); 
    }; 
}); 

, а затем использовать его в HTML, как это:

<li class="list-item" ng-repeat="item in items" key-navigation> 
        {{item.name}} 
       </li> 
+4

Использование jquery внутри вашей директивы не рекомендуется. попробуйте изменить его с помощью самого углового элемента. –

4

Этот вопрос был несколько месяцев, прежде чем это было спросил и имеет живой рабочий пример в Plunker.

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

app.controller('testCtrl',function ($scope, $window) { 
$scope.console = $window.console; 

$scope.records = []; 
for (var i = 1; i <= 9; i++) { 
$scope.records.push({ id: i, navIndex: i, name: 'record ' + i}); 
} 

$scope.focusIndex = 3; 

$scope.open = function (index) { 
var record = $scope.shownRecords[ index ] 
console.log('opening : ', record); 
}; 

$scope.keys = []; 
$scope.keys.push({ code: 13, action: function() { $scope.open($scope.focusIndex); }}); 
$scope.keys.push({ code: 38, action: function() { $scope.focusIndex--; }}); 
$scope.keys.push({ code: 40, action: function() { $scope.focusIndex++; }}); 

И ссылка на подобный вопрос задал несколько недель, прежде чем эта нить Stackoverflow

0

Директива без JQuery

.directive('arrow', function ($timeout) { 
    return function (scope, element, attrs) { 
     element.bind("keydown keypress", function (event) { 
      if (event.which === 38) { 
       var prevNode = element[0].previousElementSibling; 
       var prev = angular.element(prevNode); 
       prev[0].focus(); 
      } 
      if (event.which === 40) { 
       var target = element.next(); 
       target[0].focus(); 
      } 
     }); 
    }; 
}); 

Usages в HTML

<tr arrow> 
    <td>test 1</td>      
</tr> 
<tr arrow> 
    <td>test 2</td>      
</tr> 
Смежные вопросы