我明白了这一点。这一声闷响将使用回车键和所有箭头键(上、下、左、右)进行导航。感谢@Armen 为我指明了正确的方向。
<div ng-app="myApp">
<div ng-controller="TestingCtrl">
<table navigatable>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="p in persons">
<td>
<input type="text" ng-model="p.name">
</td>
<td>
<input type="text" ng-model="p.age">
</td>
<td>
<button ng-click="add($index)">Add new person</button>
</td>
</tr>
</tbody>
</table>
</div>
angular.module("myApp", [])
.controller("TestingCtrl", ["$scope",
function TestingCtrl($scope) {
$scope.persons = [{
name: 'Alice',
age: 20
}, {
name: 'Bob',
age: 30
}];
$scope.add = function(index) {
var newPerson = function() {
return {
name: '',
age: ''
};
};
$scope.persons.splice(index + 1, 0, new newPerson());
}
}
])
.directive('navigatable', function() {
return function(scope, element, attr) {
element.on('keypress.mynavigation', 'input[type="text"]', handleNavigation);
function handleNavigation(e) {
var arrow = {left: 37, up: 38, right: 39, down: 40};
// select all on focus
element.find('input').keydown(function(e) {
// shortcut for key other than arrow keys
if ($.inArray(e.which, [arrow.left, arrow.up, arrow.right, arrow.down]) < 0) {
return;
}
var input = e.target;
var td = $(e.target).closest('td');
var moveTo = null;
switch (e.which) {
case arrow.left:
{
if (input.selectionStart == 0) {
moveTo = td.prev('td:has(input,textarea)');
}
break;
}
case arrow.right:
{
if (input.selectionEnd == input.value.length) {
moveTo = td.next('td:has(input,textarea)');
}
break;
}
case arrow.up:
case arrow.down:
{
var tr = td.closest('tr');
var pos = td[0].cellIndex;
var moveToRow = null;
if (e.which == arrow.down) {
moveToRow = tr.next('tr');
}
else if (e.which == arrow.up) {
moveToRow = tr.prev('tr');
}
if (moveToRow.length) {
moveTo = $(moveToRow[0].cells[pos]);
}
break;
}
}
if (moveTo && moveTo.length) {
e.preventDefault();
moveTo.find('input,textarea').each(function(i, input) {
input.focus();
input.select();
});
}
});
var key = e.keyCode ? e.keyCode : e.which;
if (key === 13) {
var focusedElement = $(e.target);
var nextElement = focusedElement.parent().next();
if (nextElement.find('input').length > 0) {
nextElement.find('input').focus();
} else {
nextElement = nextElement.parent().next().find('input').first();
nextElement.focus();
}
}
}
};
})
我已经从不同来源进行了一些复制/粘贴。需要重构。