Атрибут входного автофокуса
У меня есть места в моем коде, где у меня есть это:
<input data-ng-disabled="SOME_SCOPE_VARIABLE" />
Я хотел бы также использовать его так:
<input data-ng-autofocus="SOME_SCOPE_VARIABLE" />
Или даже лучше, имитируя стиль ng:
<input data-ng-attribute="{autofocus: SOME_SCOPE_VARIABLE}" />
Это существует в текущей версии AngularJS? Я заметил в коде код BOOLEAN_ATTR, который получает все attr, которые поддерживает AngularJS. Я не хочу изменять это, опасаясь изменения версий и забывая обновить.
Ответы
Ответ 1
Обновление. У AngularJS теперь есть директива ngFocus
, которая оценивает выражение в фокусе, но я упоминаю об этом здесь для полноты.
Текущая версия AngularJS не имеет директивы фокуса, но она находится в дорожной карте. Кстати, мы вчера angular.module('ng').directive('ngFocus', function($timeout) {
return {
link: function ( scope, element, attrs ) {
scope.$watch( attrs.ngFocus, function ( val ) {
if ( angular.isDefined( val ) && val ) {
$timeout( function () { element[0].focus(); } );
}
}, true);
element.bind('blur', function () {
if ( angular.isDefined( attrs.ngFocusLost ) ) {
scope.$apply( attrs.ngFocusLost );
}
});
}
};
});
Что работает с переменной области видимости по вашему запросу:
<input type="text" ng-focus="isFocused" ng-focus-lost="loseFocus()">
Здесь сценарий:
Ответ 2
Вы можете сделать это с помощью встроенных привязок атрибутов ngAttr.
<input ng-attr-autofocus="{{SOME_SCOPE_VARIABLE}}">
Атрибут автофокуса будет добавлен, если SOME_SCOPE_VARIABLE
определен (даже если он false
), и будет удален, если он undefined
. Поэтому я заставляю значения фальши быть undefined
.
$scope.SOME_SCOPE_VARIABLE = someVar || undefined;
Ответ 3
Эта директива должна делать трюк:
angular.module('utils.autofocus', [])
.directive('autofocus', ['$timeout', function($timeout) {
return {
restrict: 'A',
scope: {'autofocus':'='}
link : function($scope, $element) {
$scope.$watch 'autofocus', function(focus){
if(focus){
$timeout(function() {
$element[0].focus();
});
}
}
}
}
}]);
Взято отсюда: https://gist.github.com/mlynch/dd407b93ed288d499778
Ответ 4
scope.doFocus = function () {
$timeout(function () {
document.getElementById('you_input_id').focus();
});
};
Ответ 5
То, что я сделал, - это регулярная автофокусировка на моих входах: <input autofocus>
И затем я устанавливаю фокус на первый видимый вход с автофокусом, когда angular готов:
angular.element(document).ready(function() {
$('input[autofocus]:visible:first').focus();
});
Надеюсь, что это поможет.
Ответ 6
Я сделал это с двумя настраиваемыми директивами, примерно так:
(function(angular) {
'use strict';
/* @ngInject */
function myAutoFocus($timeout) {
return {
restrict: 'A',
link: function(scope, element) {
$timeout(function() {
element[0].focus();
}, 300);
}
};
}
function myFocusable() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var focusMethodName = attrs.myFocusable;
scope[focusMethodName] = function() {
element[0].focus();
};
}
};
}
angular
.module('myFocusUtils', [])
.directive('myAutoFocus', myAutoFocus)
.directive('myFocusable', myFocusable);
}(angular));
Если вы добавите атрибут my-auto-focus
в элемент, он получит фокус после 300 мс. Я устанавливаю значение 300 вместо 0, чтобы другие компоненты асинхронного ввода загружались до установки фокуса.
Атрибут my-focusable
создаст функцию в текущей области. Эта функция будет устанавливать фокус на элемент при вызове. Поскольку это создает что-то в области видимости, будьте осторожны, чтобы избежать переопределения чего-либо.
Таким образом вам не нужно добавлять что-то в цикл Angular digest (watch
) и делать это целиком в представлении:
<input my-focusable="focusOnInput"></input>
<button ng-click="focusOnInput()">Click to focus</button>
Я создал JSFiddle, чтобы показать директиву myFocusable
: http://jsfiddle.net/8shLj3jc/
По какой-то причине я не знаю, директива myAutoFocus
не работает в JSFiddle, но она работает на моей странице.
Ответ 7
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<div ng-repeat="x in names">
<input ng-attr-focus={{$first}} value="{{x.name + ', ' + x.country }}" />
</div>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('namesCtrl', function($scope) {
$scope.names = [
{name:'x1',country:'y1'},
{name:'x2',country:'y2'},
{name:'x3',country:'y3'}
];
});
myApp.directive("focus", function(){
return {
restrict: "A",
link: function link(scope, element, attrs) {
if(JSON.parse(attrs.focus)){
element[0].focus();
}
}
};
});
</script>
</body>
</html>
создал выше настраиваемую директиву для одного из моих вариантов использования.
- всегда фокусируется на первом элементе ввода.
- работает для ajax-данных, кнопок назад/вперед браузера.
- Протестировано на chrome и firefox (автофокусировка по умолчанию здесь не поддерживается)
JSON.parse используется для анализа строки "true", возвращаемой из html в boolean true в JS.
другой способ использования attrs.focus === "true" для условия if.
Ответ 8
Создайте такую директиву
.directive('autoFocus', ['$timeout', function ($timeout) {
return {
restrict: 'A',
link: function ($scope, $element) {
$timeout(function () {
$element[0].focus();
});
}
}
<input type="text" auto-focus class="form-control msd-elastic" placeholder="">