在AngularJS中,“Angular的方法”是什么?
更具体的要求:
当打开一个模态时,将焦点设置在这个模态内预定义的<input>上。 每次<input>变得可见时(例如,通过单击某个按钮),将焦点设置在它上。
我尝试用自动对焦来实现第一个要求,但这只在Modal第一次打开时有效,并且只在某些浏览器中有效(例如在Firefox中它不起作用)。
在AngularJS中,“Angular的方法”是什么?
更具体的要求:
当打开一个模态时,将焦点设置在这个模态内预定义的<input>上。 每次<input>变得可见时(例如,通过单击某个按钮),将焦点设置在它上。
我尝试用自动对焦来实现第一个要求,但这只在Modal第一次打开时有效,并且只在某些浏览器中有效(例如在Firefox中它不起作用)。
当前回答
如果你正在使用modalInstance并且拥有对象,你可以在打开模式后使用“then”来执行操作。如果你没有使用modalInstance,并硬编码打开模态,你可以使用事件。$timeout不是一个好的解决方案。
你可以做(Bootstrap3):
$("#" + modalId).on("shown.bs.modal", function() {
angular.element("[name='name']").focus();
});
在modalInstance中,您可以查看如何在打开modal后执行代码的库。
不要像这样使用$timeout, $timeout可以是0、1、10、30、50、200或更多,这将取决于客户端计算机,以及打开模式的进程。
不要使用$timeout,让方法告诉你什么时候可以聚焦;)
希望这对大家有所帮助!:)
其他回答
下面的指令对我来说很管用。对输入使用相同的autofocus html属性。
.directive('autofocus', [function () {
return {
require : 'ngModel',
restrict: 'A',
link: function (scope, element, attrs) {
element.focus();
}
};
}])
如果所需的焦点元素被注入到指令模板中,前面的所有答案都将不起作用。 下面的指令既适用于简单元素,也适用于指令注入的元素(我用typescript写的)。它接受内部可聚焦元素的选择器。如果你只需要关注self元素——不要向指令发送任何选择器参数:
module APP.Directives {
export class FocusOnLoadDirective implements ng.IDirective {
priority = 0;
restrict = 'A';
constructor(private $interval:any, private $timeout:any) {
}
link = (scope:ng.IScope, element:JQuery, attrs:any) => {
var _self = this;
var intervalId:number = 0;
var clearInterval = function () {
if (intervalId != 0) {
_self.$interval.cancel(intervalId);
intervalId = 0;
}
};
_self.$timeout(function(){
intervalId = _self.$interval(function () {
let focusableElement = null;
if (attrs.focusOnLoad != '') {
focusableElement = element.find(attrs.focusOnLoad);
}
else {
focusableElement = element;
}
console.debug('focusOnLoad directive: trying to focus');
focusableElement.focus();
if (document.activeElement === focusableElement[0]) {
clearInterval();
}
}, 100);
scope.$on('$destroy', function () {
// Make sure that the interval is destroyed too
clearInterval();
});
});
};
public static factory = ():ng.IDirectiveFactory => {
let directive = ($interval:any, $timeout:any) => new FocusOnLoadDirective($interval, $timeout);
directive.$inject = ['$interval', '$timeout'];
return directive;
};
}
angular.module('common').directive('focusOnLoad', FocusOnLoadDirective.factory());
}
简单元素的使用示例:
<button tabindex="0" focus-on-load />
内部元素的使用示例(通常用于动态注入元素,如directive with template):
<my-directive focus-on-load="input" />
你可以使用任何jQuery选择器来代替“input”
以编程方式调用元素上的任何操作:click(), focus(), select()…
用法:
<a href="google.com" auto-action="{'click': $scope.autoclick, 'focus': $scope.autofocus}">Link</a>
指令:
/**
* Programatically Triggers given function on the element
* Syntax: the same as for ng-class="object"
* Example: <a href="google.com" auto-action="{'click': autoclick_boolean, 'focus': autofocus_boolean}">Link</a>
*/
app.directive('focusMe', function ($timeout) {
return {
restrict: 'A',
scope: {
autoAction: '<',
},
link: function (scope, element, attr) {
const _el = element[0];
for (const func in scope.autoAction) {
if (!scope.autoAction.hasOwnProperty(func)) {
continue;
}
scope.$watch(`autoAction['${func}']`, (newVal, oldVal) => {
if (newVal !== oldVal) {
$timeout(() => {
_el[func]();
});
}
});
}
}
}
});
要解决这个问题,最好在controller或ng-init中设置初始化变量:
<input ng-init="autofocus=true" auto-action="{'focus': autofocus}">
只是顺便送点咖啡。
app.directive 'ngAltFocus', ->
restrict: 'A'
scope: ngAltFocus: '='
link: (scope, el, attrs) ->
scope.$watch 'ngAltFocus', (nv) -> el[0].focus() if nv
我发现使用一般的表达方式很有用。这样你就可以在输入文本有效时自动移动焦点
<button type="button" moo-focus-expression="form.phone.$valid">
或者当用户完成一个固定长度的字段时自动聚焦
<button type="submit" moo-focus-expression="smsconfirm.length == 6">
当然还有加载后的重点
<input type="text" moo-focus-expression="true">
该指令的代码:
.directive('mooFocusExpression', function ($timeout) {
return {
restrict: 'A',
link: {
post: function postLink(scope, element, attrs) {
scope.$watch(attrs.mooFocusExpression, function (value) {
if (attrs.mooFocusExpression) {
if (scope.$eval(attrs.mooFocusExpression)) {
$timeout(function () {
element[0].focus();
}, 100); //need some delay to work with ng-disabled
}
}
});
}
}
};
});