Input autofocus attribute
我的代码中有地方,我有这个:
1 | <input data-ng-disabled="SOME_SCOPE_VARIABLE" /> |
我也希望能够像这样使用它:
1 | <input data-ng-autofocus="SOME_SCOPE_VARIABLE" /> |
甚至更好,模仿ng-style的完成方式:
1 | <input data-ng-attribute="{autofocus: SOME_SCOPE_VARIABLE}" /> |
当前版本的AngularJS中是否存在这种情况? 我注意到代码中有一个BOOLEAN_ATTR,它获取AngularJS支持的所有attr。 我不想修改它,因为害怕更改版本而忘记更新。
更新:AngularJS现在有一个
当前版本的AngularJS没有焦点指令,但它在路线图中。巧合的是,我们昨天在邮件列表上谈到了这一点,我想出了这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 ); } }); } }; }); |
这可以按照您的要求处理范围变量:
1 | <input type="text" ng-focus="isFocused" ng-focus-lost="loseFocus()"> |
这是一个小提琴:http://jsfiddle.net/ANfJZ/39/
您可以使用内置的ngAttr属性绑定来完成此操作。
1 | <input ng-attr-autofocus="{{SOME_SCOPE_VARIABLE}}"> |
如果定义了
1 | $scope.SOME_SCOPE_VARIABLE = someVar || undefined; |
这个指令应该做的伎俩:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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
1 2 3 4 5 | scope.doFocus = function () { $timeout(function () { document.getElementById('you_input_id').focus(); }); }; |
所以没有$ timeout你也可以像这样使用自动对焦 -
1 2 3 4 | <input type="text" ng-show="{{condition}}" class='input-class'></input> angular.element(document).ready(function(){ angular.element('.input-class')[0].focus(); }); |
创建这样的指令
1 2 3 4 5 6 7 8 9 10 11 12 13 | .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=""> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <!DOCTYPE html> <html> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"> <body> <input ng-attr-focus={{$first}} value="{{x.name + ', ' + x.country }}" /> 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(); } } }; }); </body> </html> |
为我的一个用例创建了上面的自定义指令。
- 始终专注于第一个输入元素。
- 适用于ajax数据,浏览器后退/前进按钮。
- 在chrome和firefox上测试(此处不支持默认自动对焦)
JSON.parse用于将从html返回的字符串"true"解析为JS中的布尔值true。
对于if条件,使用attrs.focus ==="true"的另一种方法。
我用两个自定义指令做了这个,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | (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)); |
如果将属性
属性
这样您就不需要向Angular的摘要周期(
1 2 | <input my-focusable="focusOnInput"></input> <button ng-click="focusOnInput()">Click to focus</button> |
我创建了一个JSFiddle来显示
由于某些原因我不知道,
我所做的是在输入上使用常规自动对焦:
然后,当角度准备就绪时,我将焦点设置在第一个可见光输入的自动对焦上:
1 2 3 | angular.element(document).ready(function() { $('input[autofocus]:visible:first').focus(); }); |
希望这可以帮助。