问题
Similar to Google Login page, I want to have autofocus on input element after on click event. I have tried @ViewChild('id') and document.getElementId('id'). Both of it doesn't work. It's always null or undefined. How can I achieve this?
<mat-form-field class="example-full-width col-sm-4">
<input autofocus id="login-username" matInput
formControlName="userName" minlength="5" maxlength="20"
name="userName" placeholder="Username" required #input>
</mat-form-field>
<div class="col-sm-12">
<button (click)="changeView()" type="button" mat-raised-
button color="primary">Next</button>
</div>
<mat-form-field class="example-full-width col-sm-4"
#passwordInput>
<input autofocus type="password" matInput
placeholder="Password" minlength="5" maxlength="20"
formControlName="userPassword" #passwordInput>
</mat-form-field>
回答1:
Unfortunately all other solutions do not work with autofocusing matInput at the moment of rendering.
The reason is that one should use a high-level api of the matInput instead of attempting to focus the input itself.
What should be done instead is calling matInput.focus()
. Here is a simple directive that uses this approach:
import { Directive, OnInit } from '@angular/core';
import { MatInput } from '@angular/material';
@Directive({
selector: '[matInputAutofocus]',
})
export class AutofocusDirective implements OnInit {
constructor(private matInput: MatInput) { }
ngOnInit() {
setTimeout(() => this.matInput.focus());
}
}
The timeout is required to delay focusing the element because matInput does not properly function at the moment of creating yet. Usage:
<mat-form-field>
<input type="text" matInput matInputAutofocus>
</mat-form-field>
Of course, naming the selector matInputAutofocus
is dangerous because material itself can come to this solution one day. Use it on your own risk or just rename with your prefix (recommended).
回答2:
If you want to set focus to an Input field as soon as the page loads, you can do it simply by applying HTML attribute to that element, such as :
<input type="text" #input1 autofocus>
Else if you want to do this from your component.ts conditionally, use:
import { Component, ElementRef, ViewChild, AfterViewInit} from
'@angular/core';
...
@ViewChild('input1') inputEl:ElementRef;
ngAfterViewInit() {
this.inputEl.nativeElement.focus();
}
Or you can use:
First import the renderer2 from @angular/core and then,
const element = this.renderer.selectRootElement('#input1');
setTimeout(() => element.focus(), 0);
Whatever you seems to be comfortable with your existing code.
回答3:
When you use Angular Material, you can use cdkFocusInitial
to tell the library where you want to focus after component is ready. No native approaches are required:
<mat-form-field class="example-full-width">
<mat-label>My Label</mat-label>
<textarea
cdkFocusInitial <---------
cdkTextareaAutosize
matInput>
</textarea>
</mat-form-field>
回答4:
You need to use template ref to input element then use ViewChild it will work
Example: https://stackblitz.com/edit/angular-frqm8b
<mat-form-field class="example-full-width col-sm-4">
<input autofocus id="login-username" matInput
formControlName="userName" minlength="5" maxlength="20"
name="userName" placeholder="Username" required #input>
</mat-form-field>
<div class="col-sm-12">
<button (click)="changeView()" type="button" mat-raised-
button color="primary">Next</button>
</div>
<mat-form-field class="example-full-width col-sm-4"
>
<input autofocus type="password" matInput
****#passwordInput****
placeholder="Password" minlength="5" maxlength="20"
formControlName="userPassword" #passwordInput>
</mat-form-field>
来源:https://stackoverflow.com/questions/51510936/how-to-set-autofocus-on-a-matinput-element-on-click-event-in-angular-6