如何在输入字段上设置焦点? [英] How to set focus on input field?

查看:37
本文介绍了如何在输入字段上设置焦点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 AngularJS 中将焦点设置在输入字段上的Angular 方式"是什么?

更具体的要求:

  1. Modal 打开时,将焦点设置在预定义的 <input> 在这个 Modal 中.
  2. 每当 变得可见(例如通过单击某个按钮)时,将焦点放在它上面.

我尝试使用 autofocus 实现第一个要求,但这仅适用当第一次打开 Modal 时,并且仅在某些浏览器中(例如在 Firefox 中它不起作用).

任何帮助将不胜感激.

解决方案

  1. 当一个 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));});}};}]);

Plunker

似乎需要 $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;//});}});}};});

Plunker

<小时>

更新 7/2013:我看到一些人使用我原来的隔离范围指令,然后在嵌入输入字段(即模式中的输入字段)方面遇到问题.没有新作用域(或者可能是新的子作用域)的指令应该可以减轻一些痛苦.所以上面我更新了不使用隔离范围的答案.以下是原答案:

1. 的原始答案,使用隔离范围:

名称:

app.directive('focusMe', function($timeout) {返回 {范围:{触发器:'@focusMe'},链接:函数(范围,元素){scope.$watch('trigger', function(value) {if(value === "true") {$超时(功能(){元素[0].focus();});}});}};});

Plunker.

2. 的原始答案,使用隔离范围:

app.directive('focusMe', function($timeout) {返回 {范围:{触发器:'=focusMe'},链接:函数(范围,元素){scope.$watch('trigger', function(value) {如果(值 === 真){//console.log('trigger',value);//$超时(函数(){元素[0].focus();scope.trigger = false;//});}});}};});

Plunker.

由于我们需要重置指令中的 trigger/focusInput 属性,因此 '=' 用于双向数据绑定.在第一个指令中,'@' 就足够了.另请注意,当使用@"时,我们将触发器值与true"进行比较,因为 @ 总是产生一个字符串.

What is the 'Angular way' to set focus on input field in AngularJS?

More specific requirements:

  1. When a Modal is opened, set focus on a predefined <input> inside this Modal.
  2. 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.

解决方案

  1. 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));
            });
        }
    };
}]);

Plunker

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;
          //});
        }
      });
    }
  };
});

Plunker


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(); 
          });
        }
      });
    }
  };
});

Plunker.

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;
          //});
        }
      });
    }
  };
});

Plunker.

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屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆