如何使用Angular4按元素id设置焦点

时间:2017-10-13 00:02:01

标签: angular angular-forms

我是Angular的新手,我正在尝试使用它将焦点设置为id为“input1”的输入。我使用以下代码:

@ViewChild('input1') inputEl: ElementRef;

然后在组件中:

 this.inputEl.nativeElement.focus();

但它不起作用。我究竟做错了什么?任何帮助将不胜感激。

7 个答案:

答案 0 :(得分:38)

<强>组件

import { Component, ElementRef, ViewChild, AfterViewInit} from '@angular/core';
... 

@ViewChild('input1') inputEl:ElementRef;

ngAfterViewInit() {
      setTimeout(() => this.inputEl.nativeElement.focus());
}

<强> HTML

<input type="text" #input1>

答案 1 :(得分:16)

@ Z.Bagley提到的问题中的一个答案给了我答案。我不得不将@ angular / core中的Renderer2导入到我的组件中。然后:

const element = this.renderer.selectRootElement('#input1');

setTimeout(() => element.focus, 0);

谢谢@MrBlaise的解决方案!

答案 2 :(得分:1)

这是一个Angular4 +指令,您可以在任何组件中重复使用。基于Niel T在this question中的答案中给出的代码。

import { NgZone, Renderer, Directive, Input } from '@angular/core';

@Directive({
    selector: '[focusDirective]'
})
export class FocusDirective {
    @Input() cssSelector: string

    constructor(
        private ngZone: NgZone,
        private renderer: Renderer
    ) { }

    ngOnInit() {
        console.log(this.cssSelector);
        this.ngZone.runOutsideAngular(() => {
            setTimeout(() => {
                this.renderer.selectRootElement(this.cssSelector).focus();
            }, 0);
        });
    }
}

您可以在组件模板中使用它,如下所示:

<input id="new-email" focusDirective cssSelector="#new-email"
  formControlName="email" placeholder="Email" type="email" email>

为输入提供id并将id传递给指令的cssSelector属性。或者你可以传递你喜欢的任何cssSelector。

Niel T的评论:

  

因为我唯一要做的就是把重点放在一个元素上,我   我不需要关心变化检测,所以我可以   在Angular之外运行对renderer.selectRootElement的调用。因为   我需要给新部分渲染时间,元素部分是   包装在超时中以允许渲染线程有时间赶上   在尝试元素选择之前。一旦完成所有设置,我   可以使用基本的CSS选择器简单地调用元素。

答案 3 :(得分:1)

这对我有帮助(离子,但想法是一样的) https://mhartington.io/post/setting-input-focus/

模板中的

<ion-item>
      <ion-label>Home</ion-label>
      <ion-input #input type="text"></ion-input>
</ion-item>
<button (click)="focusInput(input)">Focus</button>
控制器中的

  focusInput(input) {
    input.setFocus();
  }

答案 4 :(得分:1)

这是可以在任何组件中使用的指令:

import { NgZone, Directive, ElementRef, AfterContentInit, Renderer2 } from '@angular/core';

@Directive({
    selector: '[appFocus]'
})
export class FocusDirective implements AfterContentInit {
    constructor(private el: ElementRef, private zone: NgZone, private renderer: Renderer2) {}

    ngAfterContentInit() {
        this.zone.runOutsideAngular(() => setTimeout(() => {
            this.renderer.selectRootElement(this.el.nativeElement).focus();
        }, 0));
    }
}

使用:

<input type="text" appFocus>

答案 5 :(得分:0)

在一些搜索之后我也面临同样的问题我找到了一个很好的解决方案,因为@GreyBeardedGeek意味着setTimeout是这个解决方案的关键。他是完全正确的。在您的方法中,您只需要添加setTimeout,您的问题就会得到解决。

setTimeout(() => this.inputEl.nativeElement.focus(), 0);

答案 6 :(得分:0)

简单地可以使用scrollIntoView作为下面的例子并随时调用该方法

<div id="elementID"></div>
 ngAfterViewInit(): void 
{
const element = document.querySelector("#elementID");
  element.scrollIntoView(true);}