Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular ngAfterViewInit element focus not workin

When loading a component, I want you to focus on the first element after initialization. I found a tutorial for this, but it doesn't want to work for me.

https://davidmcintosh.medium.com/auto-focusing-an-angular-input-the-easy-way-part-1-dcb1799e025f

But if I put it in a timer that is 0 then it works great. But I don't want to use timer.

ngAfterViewInit(): void {
    timer(0).subscribe(() => this.firstElement.nativeElement.focus());
}

Why do I need a timer with such a ridiculous value?

Here is my HTML code:

<p class="news-title" tabindex="0" #firstElement>{{ 'news.title' | translate }}</p>
<ul class="news-list" role="list">
    <li role="listitem" tabindex="0" class="list-item">{{ 'news.item-1' | translate }}</li>
    <li role="listitem" tabindex="0" class="list-item">{{ 'news.item-2' | translate }}</li>
    <li role="listitem" tabindex="0" class="list-item">{{ 'news.item-3' | translate }}</li>
</ul>
like image 867
Bálint Bakos Avatar asked Sep 07 '25 04:09

Bálint Bakos


1 Answers

It is working for me, since your <p> tag is static which would always be there, you can query viewChild with {static: true}, that case it would query the element before change detaction, see stackblitz.

  @ViewChild('firstElement', {read: ElementRef, static: true})
  firstElement?: ElementRef<unknown>;

  ngAfterViewInit(): void {
    (this.firstElement?.nativeElement as any).focus();
  }

Better solution would be use material's A11y CDK cdkTrapFocusAutoCapture, see stackblitz

<p cdkTrapFocus="false" cdkTrapFocusAutoCapture class="news-title" tabindex="0" #firstElement>{{ 'news.title' }}</p>
<ul class="news-list" role="list">
  <li role="listitem" tabindex="0" class="list-item">{{ 'news.item-1' }}</li>
  <li role="listitem" tabindex="0" class="list-item">{{ 'news.item-2' }}</li>
  <li role="listitem" tabindex="0" class="list-item">{{ 'news.item-3' }}</li>
</ul>

Note:

  • Focus can only focus on focusable element
  • Be aware whether it's your translate pipe introducing timing issue, if you are using transloco may be try to use transloco structure directive instead of pipe.
like image 102
juana pu Avatar answered Sep 10 '25 20:09

juana pu