【问题标题】:Setting focus on an input field after ng-show在 ng-show 之后将焦点设置在输入字段上
【发布时间】:2019-07-25 07:11:35
【问题描述】:

数据加载后是否可以通过控制器设置输入字段的焦点(在这种情况下通过 $resource)?

输入通过 ng-show 隐藏,直到从 API 返回数据,但我找不到将焦点设置在输入上的方法。我知道输入的 ng-model 名称,以及输入名称,这意味着我可以通过 jQuery 完成,但如果可能的话,我宁愿使用 AngularJS 方式。

我在这里尝试了很多指令示例,但它们似乎都是 1.2 之前的 ng-focus,首先依赖于按钮的 ng-click(在我的情况下不会发生)或者只是不要没用。
非常感谢收到任何提示。

【问题讨论】:

  • 如果您在页面加载时执行此操作,出于安全原因,某些浏览器将不允许您执行此操作。
  • 我希望不要这样做.

标签: angularjs angularjs-scope


【解决方案1】:

这是一个可能对你有用的简单指令

<input focus-on="!!myResourceData" />

.directive('focusOn',function($timeout) {
    return {
        restrict : 'A',
        link : function($scope,$element,$attr) {
            $scope.$watch($attr.focusOn,function(_focusVal) {
                $timeout(function() {
                    _focusVal ? $element[0].focus() :
                        $element[0].blur();
                });
            });
        }
    }
})

【讨论】:

  • 是的!就是这样-也许我没有做对,因为我看到过类似但未使用过的东西!在 HTML 标记中。谢谢你:)
  • 为什么是setTimeout?是因为这个摘要循环还没有显示元素吗? $timeout 将干净利落地完成此任务,而无需诉诸任意时间。
  • @spenhil- 你完全正确。我更新了这个例子。谢谢。
  • 我不知道是不是因为我使用了不同版本的 angular 或什么,但我必须将 $element.focus() 更改为 $element[0].focus() 和 blur() 之前的相同内容。除此之外,它为我节省了一天。
  • 您可能还需要设置$element[0].select(),但最大的问题是如果不指定超时延迟,它很可能无法工作,因为ng-hide 和ng-show 都会出现某些动画( ng-hide-animate),因此在过渡期间您可能无法设置焦点。理想情况下,您应该从元素中获取过渡期,但我希望指定一些固定的(50 毫秒)延迟也可能对您有用。
【解决方案2】:

我已将答案扩展为使用 angular 的 ng-show 和 ng-hide

app.directive('focusOnShow', function($timeout) {
    return {
        restrict: 'A',
        link: function($scope, $element, $attr) {
            if ($attr.ngShow){
                $scope.$watch($attr.ngShow, function(newValue){
                    if(newValue){
                        $timeout(function(){
                            $element[0].focus();
                        }, 0);
                    }
                })      
            }
            if ($attr.ngHide){
                $scope.$watch($attr.ngHide, function(newValue){
                    if(!newValue){
                        $timeout(function(){
                            $element[0].focus();
                        }, 0);
                    }
                })      
            }

        }
    };
})

你只需要添加属性focus-on-show

<input type="text" ng-show="editing" focus-on-show />

【讨论】:

  • 这正是我要找的,你在那里做的很棒的代码!恭喜!
  • 正是我想要的,这是迄今为止唯一有效的答案
  • 这在浏览器上运行良好,但在 iPhone 上却无法运行
【解决方案3】:

基于 koolunix 的回答,如果您只想关注输入元素,则使用 focus-on 指令查找作为元素子元素的第一个输入元素也可能很有用。

这在外部库使用指令和模板抽象输入元素的情况下很有用。

.directive('focusOn', function ($timeout) {
    return {
        restrict: 'A',
        priority: -100,
        link: function ($scope, $element, $attr) {

            $scope.$watch($attr.focusOn,
                function (_focusVal) {
                    $timeout( function () {
                        var inputElement = $element.is('input')
                            ? $element
                            : $element.find('input');

                         _focusVal ? inputElement.focus()
                                   : inputElement.blur();
                    });
                }
            );

        }
    };
});

【讨论】:

    【解决方案4】:

    您必须在控制器中使用超时,因为它必须在之前渲染 这是一个类似的示例,默认情况下隐藏搜索框

    HTML:

    <input ng-show="vm.isActive" id="searchInputBox" ></input>
    <input type="button" ng-click="vm.toggleActiveInactive();">
    

    控制器:

    vm.isActive=false;
    vm.toggleActiveInactive=toggleActiveInactive; // vm= viewmodel
    
    function toggleActiveInactive() {
              if(vm.isActive==true){
                vm.isActive=false;
              }else{
                vm.isActive=true;
    
                $timeout(function(){     
                  document.getElementById('searchBoxInput').focus()
                }, 10 );
    
              }
            }
    

    【讨论】:

      【解决方案5】:

      Angular.io 的另一个版本

      import {Directive, ElementRef, Input, OnChanges, SimpleChanges} from '@angular/core';
      
      //Directive to that toggles focus from boolean value set with focusOn
      @Directive({
        selector: '[focusOn]'
      })
      export class FocusOnDirective implements OnChanges {
        @Input('focusOn') setFocus: boolean;
      
        constructor(private hostElement: ElementRef) {}
      
        ngOnChanges(changes : SimpleChanges) {
          (!!changes.setFocus && !!changes.setFocus.currentValue) ?
            this.hostElement.nativeElement.focus() :
            this.hostElement.nativeElement.blur();
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-18
        • 1970-01-01
        • 2020-11-05
        • 1970-01-01
        • 1970-01-01
        • 2018-04-16
        相关资源
        最近更新 更多