如何在输入字段上设置焦点? [英] How to set focus on input field?
问题描述
在 AngularJS 中将焦点设置在输入字段上的Angular 方式"是什么?
更具体的要求:
- 当 Modal 打开时,将焦点设置在预定义的
<input>
在这个 Modal 中. - 每当
变得可见(例如通过单击某个按钮)时,将焦点放在它上面.
我尝试使用 autofocus
实现第一个要求,但这仅适用当第一次打开 Modal 时,并且仅在某些浏览器中(例如在 Firefox 中它不起作用).
任何帮助将不胜感激.
- 当一个 Modal 打开时,将焦点设置在这个 Modal 中预定义的 上.
定义一个指令并让它 $watch 一个属性/触发器,以便它知道什么时候聚焦元素:
名称:
app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {返回 {//scope: true,//可选地创建一个子作用域链接:函数(范围、元素、属性){var 模型 = $parse(attrs.focusMe);范围.$watch(模型,函数(值){console.log('value=', value);如果(值 === 真){$超时(函数(){元素[0].focus();});}});//要解决@blesh 的评论,请将属性值设置为false"//模糊事件:element.bind('blur', function () {console.log('模糊');scope.$apply(model.assign(scope, false));});}};}]);
似乎需要 $timeout 来提供模态渲染时间.
<块引用>'2.'每次 变得可见时(例如,通过单击某个按钮),将焦点放在它上面.
创建一个与上面基本类似的指令.观察一些范围属性,当它变为真时(在你的 ng-click 处理程序中设置它),执行 element[0].focus()
.根据您的用例,您可能需要也可能不需要 $timeout:
app.directive('focusMe', function($timeout) {返回 {链接:函数(范围,元素,属性){scope.$watch(attrs.focusMe, function(value) {如果(值 === 真){console.log('value=',value);//$超时(函数(){元素[0].focus();范围[attrs.focusMe] = false;//});}});}};});
<小时>更新 7/2013:我看到一些人使用我原来的隔离范围指令,然后在嵌入输入字段(即模式中的输入字段)方面遇到问题.没有新作用域(或者可能是新的子作用域)的指令应该可以减轻一些痛苦.所以上面我更新了不使用隔离范围的答案.以下是原答案:
1. 的原始答案,使用隔离范围:
名称:
app.directive('focusMe', function($timeout) {返回 {范围:{触发器:'@focusMe'},链接:函数(范围,元素){scope.$watch('trigger', function(value) {if(value === "true") {$超时(功能(){元素[0].focus();});}});}};});
2. 的原始答案,使用隔离范围:
app.directive('focusMe', function($timeout) {返回 {范围:{触发器:'=focusMe'},链接:函数(范围,元素){scope.$watch('trigger', function(value) {如果(值 === 真){//console.log('trigger',value);//$超时(函数(){元素[0].focus();scope.trigger = false;//});}});}};});
由于我们需要重置指令中的 trigger/focusInput 属性,因此 '=' 用于双向数据绑定.在第一个指令中,'@' 就足够了.另请注意,当使用@"时,我们将触发器值与true"进行比较,因为 @ 总是产生一个字符串.
What is the 'Angular way' to set focus on input field in AngularJS?
More specific requirements:
- When a Modal is opened, set focus on a predefined
<input>
inside this Modal. - Everytime
<input>
becomes visible (e.g. by clicking some button), set focus on it.
I tried to achieve the first requirement with autofocus
, but this works only when the Modal is opened for the first time, and only in certain browsers (e.g. in Firefox it doesn't work).
Any help will be appreciated.
- When a Modal is opened, set focus on a predefined <input> inside this Modal.
Define a directive and have it $watch a property/trigger so it knows when to focus the element:
Name: <input type="text" focus-me="shouldBeOpen">
app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
return {
//scope: true, // optionally create a child scope
link: function (scope, element, attrs) {
var model = $parse(attrs.focusMe);
scope.$watch(model, function (value) {
console.log('value=', value);
if (value === true) {
$timeout(function () {
element[0].focus();
});
}
});
// to address @blesh's comment, set attribute value to 'false'
// on blur event:
element.bind('blur', function () {
console.log('blur');
scope.$apply(model.assign(scope, false));
});
}
};
}]);
The $timeout seems to be needed to give the modal time to render.
'2.' Everytime <input> becomes visible (e.g. by clicking some button), set focus on it.
Create a directive essentially like the one above. Watch some scope property, and when it becomes true (set it in your ng-click handler), execute element[0].focus()
. Depending on your use case, you may or may not need a $timeout for this one:
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
focus input</button>
<div ng-show="showForm">
<input type="text" ng-model="myInput" focus-me="focusInput"> {{ myInput }}
<button class="btn" ng-click="showForm=false">hide form</button>
</div>
app.directive('focusMe', function($timeout) {
return {
link: function(scope, element, attrs) {
scope.$watch(attrs.focusMe, function(value) {
if(value === true) {
console.log('value=',value);
//$timeout(function() {
element[0].focus();
scope[attrs.focusMe] = false;
//});
}
});
}
};
});
Update 7/2013: I've seen a few people use my original isolate scope directives and then have problems with embedded input fields (i.e., an input field in the modal). A directive with no new scope (or possibly a new child scope) should alleviate some of the pain. So above I updated the answer to not use isolate scopes. Below is the original answer:
Original answer for 1., using an isolate scope:
Name: <input type="text" focus-me="{{shouldBeOpen}}">
app.directive('focusMe', function($timeout) {
return {
scope: { trigger: '@focusMe' },
link: function(scope, element) {
scope.$watch('trigger', function(value) {
if(value === "true") {
$timeout(function() {
element[0].focus();
});
}
});
}
};
});
Original answer for 2., using an isolate scope:
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
focus input</button>
<div ng-show="showForm">
<input type="text" focus-me="focusInput">
<button class="btn" ng-click="showForm=false">hide form</button>
</div>
app.directive('focusMe', function($timeout) {
return {
scope: { trigger: '=focusMe' },
link: function(scope, element) {
scope.$watch('trigger', function(value) {
if(value === true) {
//console.log('trigger',value);
//$timeout(function() {
element[0].focus();
scope.trigger = false;
//});
}
});
}
};
});
Since we need to reset the trigger/focusInput property in the directive, '=' is used for two-way databinding. In the first directive, '@' was sufficient. Also note that when using '@' we compare the trigger value to "true" since @ always results in a string.
这篇关于如何在输入字段上设置焦点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!