我正在使用Angular 5进行前端应用程序,我需要隐藏一个搜索框,但点击一个按钮,搜索框将显示并设置为焦点。
我已尝试使用指令左右的stackoverflow中找到的几种方法,但没有财富。
以下是示例代码:
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello</h2>
</div>
<button (click) ="showSearch()">Show Search</button>
<p></p>
<form>
<div >
<input *ngIf="show" #search type="text" />
</div>
</form>
`,
})
export class App implements AfterViewInit {
@ViewChild('search') searchElement: ElementRef;
show: false;
name:string;
constructor() {
}
showSearch(){
this.show = !this.show;
this.searchElement.nativeElement.focus();
alert("focus");
}
ngAfterViewInit() {
this.firstNameElement.nativeElement.focus();
}
搜索框未设置为焦点。 我怎样才能做到这一点?感谢。
答案 0 :(得分:31)
像这样修改show search方法
showSearch(){
this.show = !this.show;
setTimeout(()=>{ // this will make the execution after the above boolean has changed
this.searchElement.nativeElement.focus();
},0);
}
答案 1 :(得分:11)
您应该为此使用html 自动对焦:
<input *ngIf="show" #search type="text" autofocus />
注意:如果您的组件被保留并重新使用,则它将仅在第一次创建片段时自动聚焦。可以通过使用全局dom侦听器来克服此问题,该侦听器在连接dom片段时检查dom片段内的autofocus属性,然后重新应用它或通过javascript进行聚焦。
答案 2 :(得分:6)
在Angular中,您可以在HTML本身内将焦点设置为单击按钮时输入。
<button (click)="myInput.focus()">Click Me</button>
<input #myInput></input>
答案 3 :(得分:5)
此伪指令将立即显示并在元素中选择任何文本。在某些情况下,这可能需要setTimeout,尚未经过大量测试。
import { Directive, ElementRef, OnInit } from '@angular/core';
@Directive({
selector: '[appPrefixFocusAndSelect]',
})
export class FocusOnShowDirective implements OnInit {
constructor(private el: ElementRef) {
if (!el.nativeElement['focus']) {
throw new Error('Element does not accept focus.');
}
}
ngOnInit(): void {
const input: HTMLInputElement = this.el.nativeElement as HTMLInputElement;
input.focus();
input.select();
}
}
在HTML中:
<mat-form-field>
<input matInput type="text" appPrefixFocusAndSelect [value]="'etc'">
</mat-form-field>
答案 4 :(得分:3)
还有一个名为cdkFocusInitial
的DOM属性,它对输入有效。
您可以在这里了解更多信息:https://material.angular.io/cdk/a11y/overview
答案 5 :(得分:2)
要在布尔值更改后执行并避免使用超时,可以执行以下操作:
import { ChangeDetectorRef } from '@angular/core';
constructor(private cd: ChangeDetectorRef) {}
showSearch(){
this.show = !this.show;
this.cd.detectChanges();
this.searchElement.nativeElement.focus();
}
答案 6 :(得分:1)
我要权衡一下(Angular 7解决方案)
输入[appFocus] =“ focus”。...
import {AfterViewInit, Directive, ElementRef, Input,} from '@angular/core';
@Directive({
selector: 'input[appFocus]',
})
export class FocusDirective implements AfterViewInit {
@Input('appFocus')
private focused: boolean = false;
constructor(public element: ElementRef<HTMLElement>) {
}
ngAfterViewInit(): void {
// ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
if (this.focused) {
setTimeout(() => this.element.nativeElement.focus(), 0);
}
}
}
答案 7 :(得分:1)
仅使用角度模板
<input type="text" #searchText>
<span (click)="searchText.focus()">clear</span>
答案 8 :(得分:1)
我有相同的情况,这对我有用,但是我没有您拥有的“隐藏/显示”功能。因此,也许您可以先检查在始终可见的字段时是否获得焦点,然后尝试解决更改可见性时为何不起作用的原因(可能就是为什么需要施加睡眠或承诺)
要设置焦点,这是您唯一需要做的更改:
您的HTML垫输入应为:
<input #yourControlName matInput>
在您的TS类中,在变量部分(
export class blabla...
@ViewChild("yourControlName") yourControl : ElementRef;
您的按钮很好,请致电:
showSearch(){
///blabla... then finally:
this.yourControl.nativeElement.focus();
}
就是这样。 您可以在我发现的这篇文章中查看此解决方案,因此感谢-> https://codeburst.io/focusing-on-form-elements-the-angular-way-e9a78725c04f
答案 9 :(得分:0)
这在没有setTimeout的Angular 8中可以正常工作:
import {AfterContentChecked, Directive, ElementRef} from '@angular/core';
@Directive({
selector: 'input[inputAutoFocus]'
})
export class InputFocusDirective implements AfterContentChecked {
constructor(private element: ElementRef<HTMLInputElement>) {}
ngAfterContentChecked(): void {
this.element.nativeElement.focus();
}
}
说明: 好的,这是由于以下原因而起作用:更改检测。这与setTimout起作用的原因相同,但是在Angular中运行setTimeout时,它将绕过Zone.js并再次运行所有检查,并且它起作用,因为setTimeout完成时所有更改都已完成。使用正确的生命周期挂钩(AfterContentChecked),可以达到相同的结果,但优点是不会运行额外的周期。当检查并通过所有更改后,该函数将触发,并在AfterContentInit和DoCheck钩子之后运行。如果我错了,请纠正我。
在https://angular.io/guide/lifecycle-hooks上有多个生命周期和变更检测
答案 10 :(得分:0)
html:
<input [cdkTrapFocusAutoCapture]="show" [cdkTrapFocus]="show">
组件的控制器:
showSearch() {
this.show = !this.show;
}
..并且不要忘记从A11yModule导入@angular/cdk/a11y
import { A11yModule } from '@angular/cdk/a11y'
答案 11 :(得分:-1)
更简单的方法也是这样做。
let elementReference = document.querySelector('<your css, #id selector>');
if (elementReference instanceof HTMLElement) {
elementReference.focus();
}