<div class="dropdownContainer" placeholder="test" (click)="ShowDropDown()" />
<div #tref *ngIf="showDropDown == 1" class="dropdownList" (focusout)="HideDropDown()" style="border:1px solid black;" >this is my test</div>
单击dropDownContainer后,我希望dropdownList出现并重点关注它。
我尝试使用
@ViewChild("tref", {read: ElementRef}) tref: ElementRef;
方法,但是它返回undefined,因为在单击上面的div
之前,该元素在DOM中不存在。如何自动聚焦于动态 NON INPUT DOM对象?
EDIT 根据建议更新了我的代码,但这仍然不会自动关注div。
@ViewChild("tref") tref: ElementRef;
ShowDropDown() {
this.showDropDown = 1;
this.tref.nativeElement.focus();
console.log(this.tref);
}
HideDropDown(){
console.log('test out')
this.showDropDown = 0;
}
<input #tref class="dropdownContainer" placeholder="george" (click)="ShowDropDown()" />
<div tabindex="-1" (focusout)="HideDropDown()" [hidden]="showDropDown == 0" class="dropdownList" style="border:1px solid black;" >this is my test</div>
回答问题 有两个答案。
1)DIVS不能具有焦点,除非它们具有tabindex。 Stack answer
2)我需要包含setTimeout(() => this.tref.nativeElement.focus(), 1);
,因为hidden
的元素不能自动准备好接收焦点。
3)* ngIf和hidden都可以工作,一旦我完成上述修复
清理代码
import { Component, ElementRef , ViewChild } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.less']
})
export class AppComponent {
constructor() {
}
showDropDown = 0;
@ViewChild("tref") tref: ElementRef;
ShowDropDown() {
this.showDropDown = 1;
setTimeout(() => this.tref.nativeElement.focus(), 1);
}
HideDropDown(){
this.showDropDown = 0;
}
test(){ console.log('works');}
}
<div tabindex="-2" class="dropdownContainer" placeholder="george" (click)="ShowDropDown()" ></div>
<div tabindex="-1" #tref [hidden]="showDropDown == 0" class="dropdownList" style="border:1px solid black;" (click)="test()" (focusout)="HideDropDown()">this is my test</div>
答案 0 :(得分:3)
您可以在ViewChildren
和QueryList.changes
事件的帮助下,使下拉元素在可见后立即聚焦。无论元素在视图中花费多长时间,该技术都有效。
在模板中,为下拉列表tabindex
赋予div
属性:
<div class="dropdownContainer" (click)="showDropDown = true">
Click here to show the dropdown
</div>
<div #dropDownDiv *ngIf="showDropDown" tabindex="1" class="dropdownList" (focusout)="showDropDown = false">
This is the dropdown element
</div>
在代码中,使用ViewChildren
检索dropdown元素,并在QueryList.changes
中设置ngAfterViewInit
事件处理程序。当通知您该元素已变为可见时,可以将焦点设置在该元素上:
showDropDown = false;
@ViewChildren("dropDownDiv") private dropDownDivList: QueryList<ElementRef>;
ngAfterViewInit() {
this.dropDownDivList.changes.subscribe((list: QueryList<ElementRef>) => {
if (list.length > 0) {
list.first.nativeElement.focus();
}
});
}
有关演示,请参见this stackblitz。
答案 1 :(得分:1)
从*ngIf="showDropDown"
更改为[hidden]="! showDropDown"
,您应该能够在组件内部使用@ViewChild并防止出现“未决”问题。
如果仍然不起作用,则可以始终通过将click更改为(click)="ShowDropDown(tref)"
来通过click事件将元素传递给组件。请注意,为了使其正常工作,您仍然需要将* ngIf更改为[hidden]。
答案 2 :(得分:0)
如果您对这两个元素都使用了通用容器,并在容器上设置了焦点,则任何单击(包括对下拉元素的单击)都将隐藏下拉菜单-无需手动设置焦点。 (请注意,我们必须在父项上设置tabindex)。
<div class="container" (focusout)="showDropDown = false" tabindex="0">
<div class="dropdownContainer" (click)="showDropDown = true">
Click here to show the dropdown
</div>
<div #dropDownDiv *ngIf="showDropDown" tabindex="1" class="dropdownList" >
This is the dropdown element
</div>
</div>
css:
.container:focus {
outline: none;
}